跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Golang如何实现JWT认证机制

答案:使用golang-jwt/jwt库实现JWT认证,通过定义密钥和Claims结构,生成带过期时间的Token,登录接口返回Token,中间件解析验证Token并存入上下文,保护路由安全。需注意密钥安全、Token过期与失效管理。 在Go语言中实现JWT(JSON Web Token)认证机制,主要是通过生成、解析和验证Token来完成用户身份的无状态认证。下面介绍如何使用流行的 golang-jwt/jwt 库来实现完整的JWT登录认证流程。 1. 安装JWT库 使用以下命令安装官方推荐的JWT库:
go get github.com/golang-jwt/jwt/v5
2. 定义JWT配置和结构 设置密钥和过期时间,通常使用对称密钥(如HMAC)或非对称密钥(如RSA)。这里以HMAC为例:
var jwtKey = []byte("your-secret-key") // 建议从环境变量读取

type Claims struct { UserID uint json:"user_id" Email string json:"email" jwt.RegisteredClaims }

3. 生成JWT Token 用户登录成功后,生成包含用户信息的Token:
func GenerateToken(userID uint, email string) (string, error) { expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
    UserID: userID,
    Email:  email,
    RegisteredClaims: jwt.RegisteredClaims{
        ExpiresAt: jwt.NewNumericDate(expirationTime),
        IssuedAt:  jwt.NewNumericDate(time.Now()),
        NotBefore: jwt.NewNumericDate(time.Now()),
    },
}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtKey)
} 4. 解析和验证JWT Token 在受保护的接口中,从请求头提取Token并验证有效性:
func ValidateToken(tokenStr string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(token *jwt.Token) (interface{}, error) { return jwtKey, nil })
if err != nil {
    return nil, err
}

if claims, ok := token.Claims.(*Claims); token.Valid {
    return claims, nil
} else {
    return nil, errors.New("invalid token")
}
} 5. 在HTTP中间件中使用 创建一个中间件自动校验Token,用于保护需要认证的路由:
func AuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tokenHeader := r.Header.Get("Authorization") if tokenHeader == "" { http.Error(w, "Missing token", http.StatusUnauthorized) return }
    tokenStr := strings.TrimPrefix(tokenHeader, "Bearer ")

    claims, err := ValidateToken(tokenStr)
    if err != nil {
        http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
        return
    }

    // 可将用户信息存入上下文
    ctx := context.WithValue(r.Context(), "user", claims)
    next.ServeHTTP(w, r.WithContext(ctx))
})
} 6. 使用示例:登录接口 模拟登录成功后返回Token:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { // 此处应有用户名密码验证逻辑 token, err := GenerateToken(1, "user@example.com") if err != nil { http.Error(w, "Failed to generate token", http.StatusInternalServerError) return }
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"token": token})
}) 受保护的路由使用中间件: php版微信js-sdk支付接口类 php版微信js-sdk支付接口类 下载
http.Handle("/protected", AuthMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user := r.Context().Value("user").(*Claims) fmt.Fprintf(w, "Hello %s", user.Email) })))
基本上就这些。关键点在于安全存储密钥、合理设置过期时间、防止Token泄露,并在每次请求中正确验证。JWT适合分布式系统,但一旦签发无法主动失效,如需控制权限变化,可结合 黑名单 或短期Token+刷新机制。 立即学习 “ go语言免费学习笔记(深入) ”;

相关文章