Golang JWT认证实现教程

如何在Golang中实现JWT认证?能否分享一个完整的教程,包括生成Token、验证Token以及处理过期Token的具体代码示例?另外,在实际项目中如何处理JWT的安全性问题,比如密钥管理、Token刷新机制和防止重放攻击的最佳实践是什么?

3 回复

以下是一个简单的Go语言JWT认证实现步骤:

  1. 引入依赖:使用github.com/dgrijalva/jwt-go库处理JWT。

  2. 生成JWT

    • 定义用户结构体和密钥。
    • 使用jwt.NewWithClaims创建JWT实例,并设置claims(如用户ID)。
    • 调用jwt.SigningMethodHS256签名并生成token字符串。

    示例代码:

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "id": user.ID,
        "exp": time.Now().Add(time.Hour * 24).Unix(),
    })
    tokenString, err := token.SignedString([]byte("your-secret-key"))
    
  3. 验证JWT

    • 解析token并验证签名。
    • 检查过期时间等claims。

    示例代码:

    token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
        return []byte("your-secret-key"), nil
    })
    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
        userID := uint(claims["id"].(float64))
    }
    
  4. 在路由中使用JWT:将JWT解析逻辑放在中间件中,保护需要认证的路由。

这是一个基础示例,实际应用中需加强安全性,例如使用环境变量存储密钥、添加更多的claims信息等。

更多关于Golang JWT认证实现教程的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


作为屌丝程序员,来分享一个简单的JWT认证实现。首先安装github.com/dgrijalva/jwt-go库。

  1. 生成JWT:用户登录时,后端验证用户名密码,通过后生成JWT。代码如下:
import (
    "github.com/dgrijalva/jwt-go"
    "time"
)

func GenerateToken(userID uint) (string, error) {
    claims := jwt.MapClaims{
        "exp": time.Now().Add(time.Hour * 24).Unix(),
        "userId": userID,
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return token.SignedString([]byte("your-secret-key"))
}
  1. 验证JWT:中间件拦截请求,解析JWT并验证。如果有效,则放行。
func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        bearer := r.Header.Get("Authorization")
        if bearer == "" {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }
        tokenStr := strings.Split(bearer, " ")[1]
        token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
            return []byte("your-secret-key"), nil
        })
        if err != nil || !token.Valid {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }
        claims, ok := token.Claims.(jwt.MapClaims)
        if !ok {
            w.WriteHeader(http.StatusBadRequest)
            return
        }
        // 将用户ID存储到上下文中
        ctx := context.WithValue(r.Context(), "userId", uint(claims["userId"].(float64)))
        next.ServeHTTP(w, r.WithContext(ctx))
    }
}

这样就完成了基本的JWT认证流程。记得将your-secret-key换成自己的密钥。

Golang JWT认证实现教程

JWT(JSON Web Token)是一种流行的认证机制,下面是使用Golang实现JWT认证的简单步骤:

1. 安装所需库

go get github.com/dgrijalva/jwt-go
go get github.com/gin-gonic/gin  // 如果使用Gin框架

2. 基础实现代码

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// 自定义Claims结构
type CustomClaims struct {
	UserID   int    `json:"user_id"`
	Username string `json:"username"`
	jwt.StandardClaims
}

var jwtSecret = []byte("your-secret-key") // 替换为你的密钥

// 生成JWT
func GenerateToken(userID int, username string) (string, error) {
	claims := CustomClaims{
		UserID:   userID,
		Username: username,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 24).Unix(), // 有效期24小时
			Issuer:    "your-app-name",
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(jwtSecret)
}

// 验证JWT
func ParseToken(tokenString string) (*CustomClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return jwtSecret, nil
	})

	if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
		return claims, nil
	} else {
		return nil, err
	}
}

// Gin中间件
func JWTAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.Request.Header.Get("Authorization")
		if token == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供认证令牌"})
			c.Abort()
			return
		}

		claims, err := ParseToken(token)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "无效的认证令牌"})
			c.Abort()
			return
		}

		// 将用户信息存入context
		c.Set("user_id", claims.UserID)
		c.Set("username", claims.Username)
		c.Next()
	}
}

3. 使用示例

func main() {
	r := gin.Default()

	// 登录路由
	r.POST("/login", func(c *gin.Context) {
		// 验证用户凭证...
		userID := 1
		username := "admin"
		
		token, err := GenerateToken(userID, username)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "生成令牌失败"})
			return
		}
		
		c.JSON(http.StatusOK, gin.H{"token": token})
	})

	// 需要认证的路由
	r.GET("/protected", JWTAuth(), func(c *gin.Context) {
		userID := c.MustGet("user_id").(int)
		c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("欢迎用户 %d", userID)})
	})

	r.Run(":8080")
}

注意事项

  1. 密钥(jwtSecret)应该足够复杂,并妥善保管
  2. 令牌有效期应根据业务需求设置
  3. 生产环境应考虑使用更安全的签名算法(如RS256)
  4. 考虑实现令牌刷新机制
  5. 敏感操作应要求重新验证

希望这个教程对你有帮助!如需更复杂的实现,可以考虑使用成熟的认证库如github.com/golang-jwt/jwt(新版)或github.com/auth0/go-jwt-middleware

回到顶部