2020-09-26 20:22:47
JWT(JSON Web Token)是一种无状态的Token验证机制,特别适合分布式系统和API认证场景。在Go语言中,可通过github.com/golang-jwt/jwt/v5库高效实现。以下是完整的实现流程和关键注意事项。
Claims承载用户信息和标准JWT字段:
package mainimport ( "time" "github.com/golang-jwt/jwt/v5")type UserClaims struct { UserID string `json:"user_id"` Username string `json:"username"` jwt.RegisteredClaims // 嵌入标准字段}2. 生成Token使用HS256算法和密钥签名:
var jwtSecret = []byte("your-secure-secret-key") // 实际应从环境变量读取func GenerateToken(userID, username string) (string, error) { expirationTime := time.Now().Add(1 * time.Hour) claims := &UserClaims{ UserID: userID, Username: username, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(expirationTime), IssuedAt: jwt.NewNumericDate(time.Now()), Issuer: "your-app-name", }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(jwtSecret)}3. 验证Token解析并校验签名和声明:
func ValidateToken(tokenString string) (*UserClaims, error) { token, err := jwt.ParseWithClaims( tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return jwtSecret, nil }, ) if err != nil { if ve, ok := err.(*jwt.ValidationError); ok { switch { case ve.Errors&jwt.ValidationErrorExpired != 0: return nil, fmt.Errorf("token expired") case ve.Errors&jwt.ValidationErrorNotValidYet != 0: return nil, fmt.Errorf("token not valid yet") default: return nil, fmt.Errorf("validation error: %w", err) } } return nil, fmt.Errorf("parse error: %w", err) } if claims, ok := token.Claims.(*UserClaims); ok && token.Valid { return claims, nil } return nil, fmt.Errorf("invalid token")}JWT认证为现代API架构提供了高效的无状态解决方案,但需正确处理其安全特性。通过严格的密钥管理、合理的过期时间设置和必要的补充机制,可以构建既安全又可扩展的身份验证系统。