| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package auth
- import (
- "errors"
- "time"
- "github.com/golang-jwt/jwt/v5"
- )
- // JWTClaims JWT声明
- type JWTClaims struct {
- UserID uint `json:"user_id"`
- Roles []string `json:"roles"`
- jwt.RegisteredClaims
- }
- // JWTService JWT服务
- type JWTService struct {
- secretKey string
- expire int // 过期时间(秒)
- }
- // NewJWTService 创建JWT服务
- func NewJWTService(secretKey string, expire int) *JWTService {
- return &JWTService{
- secretKey: secretKey,
- expire: expire,
- }
- }
- // GenerateToken 生成JWT令牌
- func (j *JWTService) GenerateToken(userID uint, roles []string) (string, error) {
- // 创建声明
- claims := JWTClaims{
- UserID: userID,
- Roles: roles,
- RegisteredClaims: jwt.RegisteredClaims{
- ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(j.expire) * time.Second)),
- IssuedAt: jwt.NewNumericDate(time.Now()),
- NotBefore: jwt.NewNumericDate(time.Now()),
- Issuer: "web-training",
- Subject: "user-auth",
- },
- }
- // 创建令牌
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- // 签名令牌
- tokenString, err := token.SignedString([]byte(j.secretKey))
- if err != nil {
- return "", err
- }
- return tokenString, nil
- }
- // ValidateToken 验证JWT令牌
- func (j *JWTService) ValidateToken(tokenString string) (*JWTClaims, error) {
- // 解析令牌
- token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
- // 验证签名方法
- if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
- return nil, errors.New("unexpected signing method")
- }
- return []byte(j.secretKey), nil
- })
- if err != nil {
- return nil, err
- }
- // 验证令牌有效性
- if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
- return claims, nil
- }
- return nil, errors.New("invalid token")
- }
- // RefreshToken 刷新JWT令牌
- func (j *JWTService) RefreshToken(tokenString string) (string, error) {
- // 验证旧令牌
- claims, err := j.ValidateToken(tokenString)
- if err != nil {
- return "", err
- }
- // 生成新令牌
- return j.GenerateToken(claims.UserID, claims.Roles)
- }
- // ExtractTokenFromHeader 从请求头提取令牌
- func ExtractTokenFromHeader(authHeader string) (string, error) {
- if authHeader == "" {
- return "", errors.New("authorization header is empty")
- }
- parts := strings.Split(authHeader, " ")
- if len(parts) != 2 || parts[0] != "Bearer" {
- return "", errors.New("authorization header format must be Bearer {token}")
- }
- return parts[1], nil
- }
|