jwt
需要定义 Claims,这个 jwt.RegisteredClaims 很重要
go
type CustomClaims struct {
UserID uint `json:"user_id"`
Email string `json:"email"`
jwt.RegisteredClaims
}然后就是签发 token
go
var jwtSecret = []byte("your-secret-key")
func GenerateToken(userID uint, email string) (string, error) {
claims := CustomClaims{
UserID: userID,
Email: email,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 2)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtSecret)
}gin 中间件
go
func JWTAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "missing token"})
return
}
parts := strings.Split(authHeader, " ")
if len(parts) != 2 || parts[0] != "Bearer" {
c.AbortWithStatusJSON(401, gin.H{"error": "invalid token format"})
return
}
tokenString := parts[1]
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if err != nil || !token.Valid {
c.AbortWithStatusJSON(401, gin.H{"error": "invalid token"})
return
}
claims := token.Claims.(*CustomClaims)
// 写入 context
c.Set("userID", claims.UserID)
c.Set("email", claims.Email)
c.Next()
}
}go
r := gin.Default()
authGroup := r.Group("/api")
authGroup.Use(JWTAuthMiddleware())
{
authGroup.GET("/profile", ProfileHandler)
}go
func ProfileHandler(c *gin.Context) {
userID, _ := c.Get("userID")
c.JSON(200, gin.H{
"user_id": userID,
})
}