Skip to content

Instantly share code, notes, and snippets.

Last active Aug 29, 2015
What would you like to do?
Go + Auth0

Install deps

go get
go get


go run main.go

Open browser at http://localhost:8080

This sample has a pre-configured client id and secret. You can configure it with your own.

Note: the session depedency is optional. It's used here to store the user profile and tokens but it can be easily replaced with something else.

package main
import (
var (
// Register new app at and provide
// clientId (-id), clientSecret (-secret) and callbackURL (-redirect)
// as imput arguments.
domain = ""
clientId = "OGoZgeM7K56GflfNwWCwEIMg9kzQ5Ome"
clientSecret = "tfK3imkasjtRFRR7ss-iRSX2BiclNWwNYqNdzQ85jIJzuQg2biSQw2WjShCOitT9"
callbackURL = "http://localhost:8080/callback"
var sessionManager *session.Manager
func init() {
sessionManager, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":3600}`)
go sessionManager.GC()
var router *mux.Router
func main() {
router = mux.NewRouter()
http.HandleFunc("/", router.ServeHTTP)
router.HandleFunc("/", homeHandler).Methods("GET")
router.HandleFunc("/callback", callbackHandler).Methods("GET")
http.ListenAndServe(":8080", nil)
func homeHandler(w http.ResponseWriter, r *http.Request) {
sess := sessionManager.SessionStart(w, r)
defer sess.SessionRelease(w)
profile, ok := sess.Get("profile").(map[string]interface{})
if ok && profile != nil {
<div>Welcome %v</div>
</html>`, profile["name"], profile)
} else {
<script src=""></script>
<script type="text/javascript">
var widget = new Auth0Widget({
domain: '%v',
clientID: '%v',
callbackURL: '%v'
<button onclick="widget.signin({ scope: 'openid profile' })">Login</button>
</html>`, domain, clientId, callbackURL)
func callbackHandler(w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code")
// state can be sent on the login request to keep some value across the redirect flow
// for instance a return url. It's also used for CSRF
// state := r.URL.Query().Get("state")
token, err := ExchangeCode(code);
if err != nil {
`<html><body>Error: %v</body></html>`, err)
id_token := token["id_token"].(string)
parts := strings.Split(id_token, ".")
var claimBytes []byte
if claimBytes, err = DecodeSegment(parts[1]); err != nil {
log.Fatalf("Error decoding token: %v", string(parts[1]))
var user map[string]interface{}
if err = json.Unmarshal(claimBytes, &user); err != nil {
log.Fatalf("Error parsing json: %v", string(claimBytes))
// store profile and token in session
sess := sessionManager.SessionStart(w, r)
defer sess.SessionRelease(w)
sess.Set("profile", user)
sess.Set("id_token", token["access_token"])
sess.Set("access_token", token["id_token"])
// redirect to home (or get a return url from session or state)
http.Redirect(w, r, "/", http.StatusMovedPermanently)
func ExchangeCode(code string) (map[string]interface{}, error) {
params := url.Values{}
client := &http.Client{}
req, err := http.NewRequest("POST", "https://" + domain + "/oauth/token" , nil)
if err != nil { return nil, err }
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
params.Set("grant_type", "authorization_code")
params.Set("code", code)
params.Set("client_id", clientId)
params.Set("client_secret", clientSecret)
params.Set("redirect_uri", callbackURL)
encParams := params.Encode()
reader := strings.NewReader(encParams)
req.Body = ioutil.NopCloser(reader)
req.ContentLength = int64(len(encParams))
resp, err := client.Do(req);
if err != nil { return nil, err }
raw, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil { return nil, err }
if resp.StatusCode != 200 {
return nil, &AuthenticationError{err_code: "invalid_code", err_description: string(raw)}
var token map[string]interface{}
if err := json.Unmarshal(raw, &token); err != nil {
return nil, &AuthenticationError{err_code: "invalid_token", err_description: "unable to parse to json. raw: " + string(raw)}
return token, nil
type AuthenticationError struct {
err_code string
err_description string
func (e AuthenticationError) Error() string {
return fmt.Sprintf("%v: %v", e.err_code, e.err_description)
func DecodeSegment(seg string) ([]byte, error) {
if l := len(seg) % 4; l > 0 {
seg += strings.Repeat("=", 4-l)
return base64.URLEncoding.DecodeString(seg)
Copy link


    sess.Set("id_token", token["access_token"])
    sess.Set("access_token", token["id_token"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment