How do I add authentication with JWT with Chi in Go?

In this guide, we will explore how to implement JWT (JSON Web Tokens) authentication in a Go application using the Chi router. JWT is a popular choice for securing APIs as it ensures that the requests from clients are authenticated and authorized.

Setting Up the Project

First, make sure to have Chi and the necessary JWT package. You can install them using the following command:

go get github.com/go-chi/chi/v5
go get github.com/dgrijalva/jwt-go

Creating JWT Middleware

We need to create middleware that will validate the JWT token present in the request header.

package main

import (
    "context"
    "net/http"
    "github.com/go-chi/chi/v5"
    "github.com/dgrijalva/jwt-go"
)

var mySigningKey = []byte("secret")

func JWTMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        tokenString := r.Header.Get("Authorization")
        if tokenString == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }

        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
            return mySigningKey, nil
        })

        if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
            ctx := context.WithValue(r.Context(), "user", claims["user"])
            next.ServeHTTP(w, r.WithContext(ctx))
        } else {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
        }
    })
}

Creating a Protected Route

Now, with the middleware set up, you can create protected routes that require authentication.

func ProtectedHandler(w http.ResponseWriter, r *http.Request) {
    user := r.Context().Value("user")
    w.Write([]byte("Hello, " + user.(string)))
}

func main() {
    r := chi.NewRouter()
    
    r.Post("/login", func(w http.ResponseWriter, r *http.Request) {
        // Handle login...
        // If successful, create token and send back
    })

    r.With(JWTMiddleware).Get("/protected", ProtectedHandler)
    
    http.ListenAndServe(":3000", r)
}

Conclusion

We have successfully implemented JWT authentication using Chi in our Go application. This setup ensures that only authenticated users can access protected resources.


JWT authentication Go Chi middleware secure APIs user authentication