Skip to content

Instantly share code, notes, and snippets.

@vdparikh
Last active July 21, 2018 22:56
Show Gist options
  • Save vdparikh/893d467e147402b750485ff4cc3a0899 to your computer and use it in GitHub Desktop.
Save vdparikh/893d467e147402b750485ff4cc3a0899 to your computer and use it in GitHub Desktop.
Slack Sign In to get a permanent oauth token for the user
<html>
<head></head>
<body>
<h3>Sign In with Slack</h3>
<a id="slackURL" href="https://slack.com/oauth/authorize?scope=identity.basic,identity.email,identity.team,identity.avatar,chat:write:bot&client_id=<YOUR CLIENT ID HERE>"><img alt="Sign in with Slack" height="40" width="172" src="https://platform.slack-edge.com/img/sign_in_with_slack.png" srcset="https://platform.slack-edge.com/img/sign_in_with_slack.png 1x, https://platform.slack-edge.com/img/[email protected] 2x" />
</a>
</body>
</html>
package main
import (
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"github.com/gin-gonic/gin"
)
// SlackAuthResponse ...
type SlackAuthResponse struct {
Ok bool `json:"ok"`
Error string `json:"error"`
AccessToken string `json:"access_token"`
Scope string `json:"scope"`
User struct {
Name string `json:"name"`
ID string `json:"id"`
Email string `json:"email"`
Image24 string `json:"image_24"`
Image32 string `json:"image_32"`
Image48 string `json:"image_48"`
Image72 string `json:"image_72"`
Image192 string `json:"image_192"`
Image512 string `json:"image_512"`
} `json:"user"`
Team struct {
ID string `json:"id"`
Name string `json:"name"`
Domain string `json:"domain"`
Image34 string `json:"image_34"`
Image44 string `json:"image_44"`
Image68 string `json:"image_68"`
Image88 string `json:"image_88"`
Image102 string `json:"image_102"`
Image132 string `json:"image_132"`
Image230 string `json:"image_230"`
ImageOriginal string `json:"image_original"`
} `json:"team"`
}
func main() {
// Gin Routing
r := gin.New()
// When user clicks sign in via Slack, they are redirected to Slack Sign in page
// Upon approval they are redirected back to your website redirect_uri with a query parameter code
r.GET("/slack/auth/redirect", func(c *gin.Context) {
// Get the CODE from slack redirect request
code := c.Query("code")
// Prepare request
apiURL := "https://slack.com"
resource := "/api/oauth.access"
data := url.Values{}
data.Set("client_id", "YOUR CLIENT ID")
data.Add("client_secret", "YOUR CLIENT SECRET")
data.Add("code", code)
data.Add("redirect_uri", fmt.Sprintf("%s%s", "https://localhost/slack/auth/redirect"))
u, _ := url.ParseRequestURI(apiURL)
u.Path = resource
u.RawQuery = data.Encode()
urlStr := fmt.Sprintf("%v", u)
// Setup HTTPS client
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient := &http.Client{Transport: transport}
req, err := http.NewRequest("GET", urlStr, nil)
if err != nil {
panic(err)
}
resp, getErr := httpClient.Do(req)
if getErr != nil {
panic(getErr)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
var slackAuthResponse SlackAuthResponse
err = json.Unmarshal(body, &slackAuthResponse)
if err != nil {
panic(err)
}
if !slackAuthResponse.Ok {
log.Println("SLACK_CONNECT_ERROR: ", slackAuthResponse.Error)
return
}
// Update the user in the database and then redirect
// If you need to provide a revoke option to the user, please store the SlackAccessToken incoming value
// This token does not expire and you will be able to communicate with the user using that token
c.Redirect(http.StatusFound, "/home")
/* Revoke is a similar call to revoke API
apiURL := "https://slack.com"
resource := "/api/auth.revoke"
data := url.Values{}
data.Set("client_id", "YOUR CLIENT ID")
data.Add("client_secret", "YOUR CLIENT SECRET")
data.Add("token", sessionUser.(models.User).SlackAccessToken)
data.Add("redirect_uri", fmt.Sprintf("%s%s", viper.GetString("urls.fileserver"), "/slack/auth/redirect"))
*/
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment