答案:使用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})
})
受保护的路由使用中间件:
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语言免费学习笔记(深入)”;










