has been a popular language over the past few years known for it's simplicity and great out-of-the-box support for building web applications and for concurrency heavy processing. Similarly, (JSON Web Tokens) are turning into an increasingly popular way of authenticating users. In this post I shall go over how to create an authentication middleware for Golang that can restrict certain parts of your web app to require authentication. Golang JWT You can also apply this pattern for creation of middlewares to make any middleware that does anything you want to. If you aren't familiar with JWTs, is a great resource to get familiar with them. Basically, a JWT is a token included in the header of an HTTP request can be used to verify the user making the request. While most forms of token authentication requires a database read to verify the token belongs to an active authenticated user, when using JWTs, if the JWT can be decoded successfully, that itself guarantees it is a valid token since it has a signature field that will become invalid if any data in the token is corrupted or manipulated. You can also decide what data to encode in the JWT body, which means on successfully decoding a JWT you can also get useful data, such as a user's username or email. https://jwt.io/ Authorization The scope of this article is limited to creating a middleware in Golang to check the validity of a JWT in an incoming request. Generation of JWTs are a separate process and I will not be describing how to do that here. Setting up the web app I'm using a simple Golang web app that provides a single API endpoint - , that responds with "pong". No libraries have been used in the code below. /ping main ( ) { w.WriteHeader(http.StatusOK) w.Write([] ( )) } { http.Handle( , http.HandlerFunc(pong)) log.Fatal(http.ListenAndServe( , )) } package import "log" "net/http" func pong (w http.ResponseWriter, r *http.Request) byte "pong" func main () "/ping" ":8080" nil Here's a quick breakdown of what this does: The main function registers as the handler function for the endpoint. Then it starts an HTTP server running on port 8080. The function simply responds with a status of 200 (meaning "OK") and the text "pong". requires it's second argument to be a value that implements the interface, so is an adapter function that does just that. More on this later. pong /ping pong Handle Handler HandlerFunc So now if you run this with (Assuming the file name is ) and send a GET request to (Opening this link in your browser is an easy way) you'll get back the text . go run main.go main.go http://localhost:8080/ping pong Now I want to protect the endpoint so only incoming requests that have a valid JWT can get the required response. If the JWT is not present or is corrupted, the app should return HTTP status code 401 - Not authorized. /ping Creating a middleware A middleware for our HTTP server should be a function that takes in a function that implements the interface and returns a new function that implements the interface. http.Handler http.Handler This concept should be familiar for anyone who has used JavaScript closures, Python decorators or functional programming of some kind. But essentially, it is a function that takes a function and adds additional functionality to it. But wait - the handler function we just wrote, , does not implement this interface. So we have to take care of that. If you look in Golang's built in package you'll find that the interface just specifies that the method should be implemented for that value. In fact - we don't even have to implement this ourselves for our handler function. also provides a handy helper function called that takes in any function that accepts and as parameters, and converts it to a function that implements the interface. pong http Handler ServeHTTP http HandlerFunc ResponseWriter *Request Handler At this point it's easy to get confused between these 4 things in the package, so let me just clarify them: http - An interface with a single member - . http.Handler ServeHTTP - A function that is used to convert (and any other handler function) to a function that implements the interface. http.HandlerFunc pong Handler - A function used to associate an endpoint with a handler function. Automatically converts the handler function into a function that implements the Handler interface. We have not used this here. http.HandleFunc - Same as , except it does NOT convert the handler function into a function that implements the interface. http.Handle HandleFunc Handler Let's create the structure of a basic middleware: { http.HandlerFunc( { next.ServeHTTP(w, r) }) } . func middleware (next http.Handler) http Handler return func (w http.ResponseWriter, r *http.Request) // Do stuff As you can see, we get the request and can do anything we want with it before calling the handler function we created earlier, which is passed to our middleware as . We make use of again to convert the function we return to a function that implements interface. next HandlerFunc Handler Now you can have your middleware do whatever you want with the incoming request. What I want to do is to validate the JWT in the header of the request, so I'll start with the following changes: Authorization authHeader := strings.Split(r.Header.Get( ), ) (authHeader) != { fmt.Println( ) w.WriteHeader(http.StatusUnauthorized) w.Write([] ( )) } "Authorization" "Bearer " if len 2 "Malformed token" byte "Malformed Token" This takes the JWT token from the header. If the token is not present, it returns an unauthorized status and never calls our handler function. Authorization The expected format of the header is . Note that you can pass the JWT in the request anyway you want, but this is the widely accepted way of doing it. Bearer <token> If the token is indeed present, we'll need to decode it. For this I'm using the library, which can be installed with go-jwt go get github.com/dgrijalva/jwt-go { jwtToken := authHeader[ ] token, err := jwt.Parse(jwtToken, { _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { , fmt.Errorf( , token.Header[ ]) } [] (SECRETKEY), }) claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { ctx := context.WithValue(r.Context(), , claims) next.ServeHTTP(w, r.WithContext(ctx)) } { fmt.Println(err) w.WriteHeader(http.StatusUnauthorized) w.Write([] ( )) } } else 1 func (token *jwt.Token) ( {}, error) interface if return nil "Unexpected signing method: %v" "alg" return byte nil if "props" // Access context values in handlers like this // props, _ := r.Context().Value("props").(jwt.MapClaims) else byte "Unauthorized" We use to decode our token. The second argument to this function is a function that is used to return the secret key used to decode the token after checking if the signing method of the token is HMAC. This is because JWT can be encoded in many ways including asymmetric encryption with a public-private key pair. Here I'm using a simple secret key to decode the JWT. This must be the same secret key used to encode the JWT by the entity that generated the JWT. The signing method will not be HMAC if the key was encoded in some other way, so we check this first. jwt.Parse Note that you have to replace the variable with your secret key, which should be a string. SECRETKEY Then we obtain the claims from the token. The claims are whatever values that have been encoded in the JWT. If the decoding fails, this means the token has been corrupt or tampered with, and we return an unauthorized status. If the decoding was successful, we create a variable to hold these claims and attach them to the request instance through it's . This is done so that we can access them in our handler function (or other middlewares if we chain multiple middlewares) if needed, as mentioned in the commented out lines. "props" here is a key I used, and can be substituted with any value of your choice as long as you use the same key while trying to get data from the context. A typical use case would be to get the user ID from the claims in the handler function and use that to perform a database operation for some information that corresponds to that user. ctx Context Finally we change our earlier code to wrap the handler function in the middleware. http.Handle( , middleware(http.HandlerFunc(pong))) "/ping" The complete code looks like this: main ( ) { http.HandlerFunc( { authHeader := strings.Split(r.Header.Get( ), ) (authHeader) != { fmt.Println( ) w.WriteHeader(http.StatusUnauthorized) w.Write([] ( )) } { jwtToken := authHeader[ ] token, err := jwt.Parse(jwtToken, { _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { , fmt.Errorf( , token.Header[ ]) } [] (SECRETKEY), }) claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { ctx := context.WithValue(r.Context(), , claims) next.ServeHTTP(w, r.WithContext(ctx)) } { fmt.Println(err) w.WriteHeader(http.StatusUnauthorized) w.Write([] ( )) } } }) } { w.WriteHeader(http.StatusOK) w.Write([] ( )) } { http.Handle( , middleware(http.HandlerFunc(pong))) log.Fatal(http.ListenAndServe( , )) } package import "context" "fmt" "log" "net/http" "strings" "github.com/dgrijalva/jwt-go" . func middleware (next http.Handler) http Handler return func (w http.ResponseWriter, r *http.Request) "Authorization" "Bearer " if len 2 "Malformed token" byte "Malformed Token" else 1 func (token *jwt.Token) ( {}, error) interface if return nil "Unexpected signing method: %v" "alg" return byte nil if "props" // Access context values in handlers like this // props, _ := r.Context().Value("props").(jwt.MapClaims) else byte "Unauthorized" func pong (w http.ResponseWriter, r *http.Request) byte "pong" func main () "/ping" ":8080" nil You can use the same approach to create multiple middlewares and apply them on endpoints that need them. I hope you found this post helpful. You can find me on and . Twitter LinkedIn