Golang JWT认证实现

如何在Golang中实现JWT认证?我目前正在开发一个Web应用,需要添加用户认证功能,听说JWT是比较流行的方案。想请教:

  1. 应该使用哪个Go的JWT库比较好?
  2. 如何生成和验证JWT令牌的具体代码示例?
  3. 在实际项目中,如何处理令牌的过期和刷新?
  4. 有哪些需要注意的安全问题?
  5. 能否分享一个完整的JWT认证流程实现?
2 回复

使用Go实现JWT认证,推荐使用github.com/golang-jwt/jwt库。主要步骤:

  1. 生成JWT:使用HS256算法,设置claims和密钥签名
  2. 验证JWT:解析token,验证签名和有效期
  3. 中间件:在HTTP处理器前验证token有效性

注意:妥善保管密钥,设置合理的过期时间。

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


在Golang中实现JWT认证,可以使用github.com/golang-jwt/jwt库。以下是完整的实现示例:

1. 安装依赖

go get github.com/golang-jwt/jwt

2. 核心代码实现

package main

import (
    "fmt"
    "net/http"
    "time"
    
    "github.com/golang-jwt/jwt"
)

// JWT密钥
var jwtKey = []byte("your-secret-key")

// 用户声明结构体
type Claims struct {
    Username string `json:"username"`
    jwt.StandardClaims
}

// 生成JWT Token
func GenerateToken(username string) (string, error) {
    expirationTime := time.Now().Add(24 * time.Hour)
    
    claims := &Claims{
        Username: username,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
            IssuedAt:  time.Now().Unix(),
            Issuer:    "your-app",
        },
    }
    
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return token.SignedString(jwtKey)
}

// 验证JWT Token
func ValidateToken(tokenString string) (*Claims, error) {
    claims := &Claims{}
    
    token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
        return jwtKey, nil
    })
    
    if err != nil {
        return nil, err
    }
    
    if !token.Valid {
        return nil, fmt.Errorf("invalid token")
    }
    
    return claims, nil
}

// 登录处理
func LoginHandler(w http.ResponseWriter, r *http.Request) {
    // 验证用户名密码(简化示例)
    username := r.FormValue("username")
    password := r.FormValue("password")
    
    // 实际应用中需要验证数据库
    if username == "admin" && password == "password" {
        token, err := GenerateToken(username)
        if err != nil {
            http.Error(w, "生成token失败", http.StatusInternalServerError)
            return
        }
        
        w.Header().Set("Content-Type", "application/json")
        fmt.Fprintf(w, `{"token": "%s"}`, token)
    } else {
        http.Error(w, "用户名或密码错误", http.StatusUnauthorized)
    }
}

// 需要认证的接口
func ProtectedHandler(w http.ResponseWriter, r *http.Request) {
    tokenString := r.Header.Get("Authorization")
    if tokenString == "" {
        http.Error(w, "缺少token", http.StatusUnauthorized)
        return
    }
    
    // 去掉"Bearer "前缀
    if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
        tokenString = tokenString[7:]
    }
    
    claims, err := ValidateToken(tokenString)
    if err != nil {
        http.Error(w, "无效的token", http.StatusUnauthorized)
        return
    }
    
    w.Write([]byte(fmt.Sprintf("欢迎 %s,这是受保护的内容", claims.Username)))
}

// 中间件版本
func JWTMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        tokenString := r.Header.Get("Authorization")
        if tokenString == "" {
            http.Error(w, "缺少token", http.StatusUnauthorized)
            return
        }
        
        if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
            tokenString = tokenString[7:]
        }
        
        _, err := ValidateToken(tokenString)
        if err != nil {
            http.Error(w, "无效的token", http.StatusUnauthorized)
            return
        }
        
        next(w, r)
    }
}

func main() {
    http.HandleFunc("/login", LoginHandler)
    http.HandleFunc("/protected", ProtectedHandler)
    // 使用中间件版本
    http.HandleFunc("/api/protected", JWTMiddleware(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("通过中间件验证成功"))
    }))
    
    fmt.Println("服务器启动在 :8080")
    http.ListenAndServe(":8080", nil)
}

3. 使用示例

登录获取token:

curl -X POST http://localhost:8080/login \
  -d "username=admin&password=password"

访问受保护接口:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  http://localhost:8080/protected

4. 关键要点

  • 密钥管理: 生产环境使用环境变量或配置管理密钥
  • Token过期: 设置合理的过期时间,建议使用refresh token机制
  • 安全传输: 确保使用HTTPS传输
  • 签名算法: 推荐使用HS256或RS256

这个实现提供了完整的JWT认证流程,包括token生成、验证和中间件封装。

回到顶部