jwt.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package auth
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/golang-jwt/jwt/v5"
  6. )
  7. // JWTClaims JWT声明
  8. type JWTClaims struct {
  9. UserID uint `json:"user_id"`
  10. Roles []string `json:"roles"`
  11. jwt.RegisteredClaims
  12. }
  13. // JWTService JWT服务
  14. type JWTService struct {
  15. secretKey string
  16. expire int // 过期时间(秒)
  17. }
  18. // NewJWTService 创建JWT服务
  19. func NewJWTService(secretKey string, expire int) *JWTService {
  20. return &JWTService{
  21. secretKey: secretKey,
  22. expire: expire,
  23. }
  24. }
  25. // GenerateToken 生成JWT令牌
  26. func (j *JWTService) GenerateToken(userID uint, roles []string) (string, error) {
  27. // 创建声明
  28. claims := JWTClaims{
  29. UserID: userID,
  30. Roles: roles,
  31. RegisteredClaims: jwt.RegisteredClaims{
  32. ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(j.expire) * time.Second)),
  33. IssuedAt: jwt.NewNumericDate(time.Now()),
  34. NotBefore: jwt.NewNumericDate(time.Now()),
  35. Issuer: "web-training",
  36. Subject: "user-auth",
  37. },
  38. }
  39. // 创建令牌
  40. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  41. // 签名令牌
  42. tokenString, err := token.SignedString([]byte(j.secretKey))
  43. if err != nil {
  44. return "", err
  45. }
  46. return tokenString, nil
  47. }
  48. // ValidateToken 验证JWT令牌
  49. func (j *JWTService) ValidateToken(tokenString string) (*JWTClaims, error) {
  50. // 解析令牌
  51. token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
  52. // 验证签名方法
  53. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  54. return nil, errors.New("unexpected signing method")
  55. }
  56. return []byte(j.secretKey), nil
  57. })
  58. if err != nil {
  59. return nil, err
  60. }
  61. // 验证令牌有效性
  62. if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
  63. return claims, nil
  64. }
  65. return nil, errors.New("invalid token")
  66. }
  67. // RefreshToken 刷新JWT令牌
  68. func (j *JWTService) RefreshToken(tokenString string) (string, error) {
  69. // 验证旧令牌
  70. claims, err := j.ValidateToken(tokenString)
  71. if err != nil {
  72. return "", err
  73. }
  74. // 生成新令牌
  75. return j.GenerateToken(claims.UserID, claims.Roles)
  76. }
  77. // ExtractTokenFromHeader 从请求头提取令牌
  78. func ExtractTokenFromHeader(authHeader string) (string, error) {
  79. if authHeader == "" {
  80. return "", errors.New("authorization header is empty")
  81. }
  82. parts := strings.Split(authHeader, " ")
  83. if len(parts) != 2 || parts[0] != "Bearer" {
  84. return "", errors.New("authorization header format must be Bearer {token}")
  85. }
  86. return parts[1], nil
  87. }