Go: Integrating Auth0 JWT-middleware with multiple handlers

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")
}