package token import ( "fmt" "time" "github.com/golang-jwt/jwt/v5" ) // Claims 定义了 JWT 的声明结构 type Claims struct { UserID uint `json:"user_id"` jwt.RegisteredClaims } // TokenService 定义了 token 操作的接口 type TokenService interface { GenerateToken(userID uint) (string, error) ParseToken(tokenString string) (*Claims, error) } // tokenService 是 TokenService 接口的实现 type tokenService struct { secret []byte } // NewTokenService 创建并返回一个新的 TokenService 实例 func NewTokenService(secret []byte) TokenService { return &tokenService{secret: secret} } // GenerateToken 生成一个新的 JWT token func (s *tokenService) GenerateToken(userID uint) (string, error) { nowTime := time.Now() expireTime := nowTime.Add(24 * time.Hour) // Token 有效期为 24 小时 claims := Claims{ UserID: userID, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(expireTime), Issuer: "pig-farm-controller", }, } tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token, err := tokenClaims.SignedString(s.secret) return token, err } // ParseToken 解析并验证 JWT token func (s *tokenService) ParseToken(tokenString string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { return s.secret, nil }) // 优先检查解析过程中是否发生错误 if err != nil { return nil, err } // 只有当 token 对象有效时,才尝试获取 Claims 并验证 if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } // 如果 token 无效(例如,过期但没有返回错误,或者 Claims 类型不匹配),则返回一个通用错误 return nil, fmt.Errorf("token is invalid") }