Auth0 Home Blog Docs

Go: Integrating Auth0 JWT-middleware with multiple handlers

jwt
authentication
authorization
go
handler

#1

Hello,

I’ve gone through Auth0’s blog post regarding Go, REST API and JWT, and have had success setting that up locally. The tutorial makes use of Auth0’s Go JWT-middleware.

My issue is with integrating JWT-middleware with another existing tutorial, which has the app defined in a different way. Here, the app is itself a struct, as a way to manage a router and database connection.

When I try to set it up, none of these variations seems to work, I’m lost:

a.Router.HandleFunc("/hello2", jwtMiddleware.Handler(a.HelloWorld)).Methods(“GET”)
a.Router.Handle("/hello2", jwtMiddleware.Handler(a.HelloWorld)).Methods(“GET”)
a.Router.HandleFunc("/hello2", jwtMiddleware.HandleWithNext(a.HelloWorld)).Methods(“GET”)

For reference, GorillaMUX is being used.

What I can’t tell is, am I chaining this correctly and/or is the “a.” aspect (the app struct) getting in the way somehow.

Boil it down, another way of asking: How to integrate Auth0 JWT-middleware with this tutorial

Below is local code, copy-paste into a fresh main.go, it should build, assuming you have the Go libraries in import:

package main

import (
    "net/http"
    "log"
    "fmt"
    "time"
		"database/sql"

    _ "github.com/go-sql-driver/mysql"
		"github.com/gorilla/mux"
		//"github.com/gorilla/handlers"
		//"github.com/gorilla/context"
		"github.com/dgrijalva/jwt-go"
		"github.com/auth0/go-jwt-middleware"
)

// App struct
type App struct {
    Router *mux.Router
    DB     *sql.DB
}

// Run func
func (a *App) Run(addr string) {
    log.Fatal(http.ListenAndServe(addr, a.Router))
}

// Initialize func
func (a *App) Initialize(user, password, dbname string) {
    connectionString := fmt.Sprintf("%s:%s@tcp(localhost:8889)/%s", user, password, dbname)

    var err error
    a.DB, err = sql.Open("mysql", connectionString)
    if err != nil {
        log.Fatal(err)
    }

    a.Router = mux.NewRouter()
    a.initializeRoutes()
}

// InitializeRoutes func
func (a *App) initializeRoutes() {

    // Testing AUTH0 handler integration. What to do???

    a.Router.HandleFunc("/hello2", jwtMiddleware.HandleWithNext(a.HelloWorld)).Methods("GET")


    // Original regular routes below, for reference

    // Makes it so 'public/index.html' is called and sent to the browser (index.html contains ReactJS app)
    a.Router.Handle("/", http.FileServer(http.Dir("./public/")))

    // Allows access to public sub-directories, to serve static images, CSS and JS
    a.Router.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))

    // This prints a basic message to the browser
    a.Router.HandleFunc("/hello1", a.HelloWorld).Methods("GET")
}


// HelloWorld1 func
func (a *App) HelloWorld(w http.ResponseWriter, r *http.Request) {
    w.Write(]byte("Hello, World!"))
}



// --------------------------------------------
// Auth0 stuff begins here.
// --------------------------------------------

/* Set up a global string for our secret */
var mySigningKey = ]byte("secret")

// GetTokenHandler var
var GetTokenHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){

    // Create the token
    token := jwt.New(jwt.SigningMethodHS256)

    // Create a map to store our claims
		claims := token.Claims.(jwt.MapClaims)

    // Set token claims
    claims"admin"] = true
    claims"name"] = "Firstname Lastname"
    claims"exp"] = time.Now().Add(time.Hour * 24).Unix()

    // Sign the token with our secret
    tokenString, _ := token.SignedString(mySigningKey)

    // Finally, write the token to the browser window
    w.Write(]byte(tokenString))
})

var jwtMiddleware = jwtmiddleware.New(jwtmiddleware.Options{
    ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
    return mySigningKey, nil
    },
    SigningMethod: jwt.SigningMethodHS256,
})


// --------------------------------------------
// Finally, actually run everything
// --------------------------------------------

func main() {

    // Creates instance of App struct.
		a := App{}

    // Initialize the app with parameters used for DB stuff not included in this post.
    a.Initialize("<user>", "<pass>", "<db>")

    // Run the app on a particular address, or just a port in this case.
		a.Run(":3000")
}

#2