SoFunction
Updated on 2025-04-11

A detailed explanation of how to implement JWT authentication and authorization in Golang

In modern web applications, security is a very important topic. JWT (JSON Web Token) has been widely used in various systems as a commonly used authentication and authorization mechanism. Its advantages are lightweight, cross-platform, and well-suited for distributed systems. In this article, we will implement JWT authentication and authorization through Golang to help you build a more secure API.

What is JWT?

JWT (JSON Web Token) is an open standard (RFC 7519) used to safely transmit information in a short string between network application environments. JWT is usually used for user authentication and authorization, and it consists of three parts:

1. Header: Usually contains two parts of information, type (JWT) and signature algorithm (such as HMAC SHA256 or RSA).

2. Payload: contains the data we want to pass, usually the user's identity information or permissions, etc.

3. Signature: Ensure the integrity of the message and prevent tampering. It is generated by the header and payload signed with a private key.

The structure of JWT is as follows:

Why choose JWT?

Statelessness: JWT is self-contained, so it does not need to store session information, and is suitable for distributed systems.

Cross-platform: The structure of JWT is standardized, and JWT can be generated and parsed in almost all languages.

Flexibility: Any information can be stored in the JWT, such as user ID, permissions, expiration time, etc.

Implement JWT authentication and authorization in Golang

1. Install the required libraries

We will use the /dgrijalva/jwt-go library to generate and validate JWTs. First, use go get to install the library:

go get /dgrijalva/jwt-go

2. Create JWT generation and parsing functions

We will create a simple JWT generation and verification module that allows users to log in with their username and password and get a JWT for subsequent requests.

Generate JWT

In the file, write the JWT generation function:

package main
 
import (
    "/dgrijalva/jwt-go"
    "time"
    "log"
)
 
// The key is used to sign and verify JWTvar jwtKey = []byte("secret")
 
// User information structuretype Claims struct {
    Username string `json:"username"`
    
}
 
// Generate JWTfunc GenerateJWT(username string) (string, error) {
    expirationTime := ().Add(1 * ) // Set the JWT expiration time to 1 hour    claims := &Claims{
        Username: username,
        StandardClaims: {
            ExpiresAt: (),
        },
    }
 
    // Create a new JWT object and sign it using HMAC SHA256 algorithm    token := (jwt.SigningMethodHS256, claims)
 
    // Sign with key and return the generated JWT string    return (jwtKey)
}

Analyze JWT

Then, write a JWT parsing function, verify its validity and extract user information:

// parse JWT and return usernamefunc ParseJWT(tokenStr string) (string, error) {
    claims := &Claims{}
    token, err := (tokenStr, claims, func(token *) (interface{}, error) {
        // Return the key used when signing        return jwtKey, nil
    })
 
    if err != nil {
        return "", err
    }
 
    if ! {
        return "", err
    }
 
    return , nil
}

3. Implement the login interface

Next, we implement a login interface where users can obtain JWT by providing username and password.

package main
 
import (
    "/gin-gonic/gin"
    "net/http"
)
 
// Assuming user data, databases should be used in actual applicationsvar users = map[string]string{
    "user1": "password1",
    "user2": "password2",
}
 
func main() {
    r := ()
 
    // Login interface    ("/login", func(c *) {
        var loginData map[string]string
        if err := (&loginData); err != nil {
            (, {"error": "Invalid input"})
            return
        }
 
        username, password := loginData["username"], loginData["password"]
 
        // Verify username and password        if correctPassword, exists := users[username]; exists && correctPassword == password {
            // Generate JWT            token, err := GenerateJWT(username)
            if err != nil {
                (, {"error": "Could not generate token"})
                return
            }
 
            (, {"token": token})
        } else {
            (, {"error": "Invalid username or password"})
        }
    })
 
    (":8080")
}

4. Implement protected routing

To protect routes that require authorization, we need to write middleware to verify the JWT. These routes can only be accessed by a validated request.

// JWT verification middlewarefunc JWTMiddleware()  {
    return func(c *) {
        // Get the Authorization header        tokenStr := ("Authorization")
        if tokenStr == "" {
            (, {"error": "Missing token"})
            ()
            return
        }
 
        // parse the JWT and get the username        username, err := ParseJWT(tokenStr)
        if err != nil {
            (, {"error": "Invalid token"})
            ()
            return
        }
 
        // Add the username to the context for subsequent use        ("username", username)
        ()
    }
}
 
func main() {
    r := ()
 
    // Login interface    ("/login", func(c *) {
        var loginData map[string]string
        if err := (&loginData); err != nil {
            (, {"error": "Invalid input"})
            return
        }
 
        username, password := loginData["username"], loginData["password"]
 
        if correctPassword, exists := users[username]; exists && correctPassword == password {
            token, err := GenerateJWT(username)
            if err != nil {
                (, {"error": "Could not generate token"})
                return
            }
 
            (, {"token": token})
        } else {
            (, {"error": "Invalid username or password"})
        }
    })
 
    // Protected routes must be authenticated by JWT    authorized := ("/protected")
    (JWTMiddleware())
    ("/hello", func(c *) {
        username := ("username").(string)
        (, {
            "message": "Hello, " + username,
        })
    })
 
    (":8080")
}

5. Test JWT certification

##16bWaaVUGAdS8d39CilS9PXEtEptU809NqHfKBuiVYk=##

First, get the JWT through the /login interface:

curl -X POST http://localhost:8080/login -H "Content-Type: application/json" -d '{"username":"user1", "password":"password1"}'

Return result:

{ "token": "your-jwt-token" }

Then, use the returned JWT to access the protected route:

curl -X GET http://localhost:8080/protected/hello -H "Authorization: your-jwt-token"

Return result:

{ "message": "Hello, user1" }

Conclusion

Through the explanation of this article, you should have mastered how to use JWT for authentication and authorization in Golang. With its statelessness and cross-platform characteristics, JWT has become an ideal choice for authentication and authorization in distributed systems. You can further expand this basic authentication system, such as supporting permission control, refresh tokens and other functions.

The above is a detailed explanation of how to implement JWT certification and authorization in Golang. For more information about Golang JWT certification and authorization, please follow my other related articles!