JSON Web Tokens (JWT) are a popular method for representing claims securely between two parties. In the realm of web applications, they often serve as a way to transmit identity information (as claims) from a client to a server. In this tutorial, we’ll walk through the process of implementing JWT authentication in a Go application.
1. What is JWT?
A JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
A JWT typically looks like: xxxxx.yyyyy.zzzzz
- Header: The header (xxxxx) typically consists of two parts: the type of the token, which is JWT, and the signing algorithm.
- Payload: The payload (yyyyy) contains the claims. Claims are statements about the subject (user).
- Signature: To create the signature (zzzzz) part, you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.
2. Setting Up the Go Environment
First, you’ll need a package to work with JWTs in Go. We’ll use the github.com/golang-jwt/jwt
package:
3. Creating JWTs in Go
Let’s create a function to generate a JWT:
package main
import (
"fmt"
"github.com/golang-jwt/jwt/v4"
"time"
)
var mySigningKey = []byte("secretpassword")
func GenerateJWT() (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["authorized"] = true
claims["user"] = "John Doe"
claims["exp"] = time.Now().Add(time.Minute * 30).Unix()
tokenString, err := token.SignedString(mySigningKey)
if err != nil {
fmt.Errorf("Something went wrong: %s", err.Error())
return "", err
}
return tokenString, nil
}
4. Validating JWTs in Go
Now, let’s validate the JWT:
func ValidateToken(tokenString string) (*jwt.Token, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("There was an error")
}
return mySigningKey, nil
})
if err != nil {
return nil, err
}
return token, nil
}
5. Using JWTs for Authentication in a Go Web Application
Here’s a simple example integrating JWT generation and validation in a Go HTTP server:
package main
import (
"fmt"
"log"
"net/http"
)
func HomePage(w http.ResponseWriter, r *http.Request) {
validToken, err := GenerateJWT()
if err != nil {
fmt.Fprintf(w, err.Error())
}
clientToken := r.Header.Get("Token")
if clientToken != validToken {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "Token is not valid")
return
}
fmt.Fprintf(w, "Hello, World!")
}
func handleRequests() {
http.HandleFunc("/", HomePage)
log.Fatal(http.ListenAndServe(":9000", nil))
}
func main() {
handleRequests()
}
With this setup:
- The server creates a JWT when the homepage is accessed.
- To validate, the client needs to send the same JWT back in the header “Token”.
- This is a basic example. In real scenarios, you’d issue a token after login and check it on each request requiring authentication.
JWTs provide a powerful and flexible method for handling authentication and authorization in web applications. In Go, thanks to packages like github.com/golang-jwt/jwt
, implementing JWT-based authentication is straightforward. However, always remember to keep your signing key secret and use a secure method, preferably RSA, for added security in production applications.
Lyron Foster is a Hawai’i based African American Author, Musician, Actor, Blogger, Philanthropist and Multinational Serial Tech Entrepreneur.