Files
2026-01-06 19:36:42 +08:00

91 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"ai_xhs/config"
"context"
"errors"
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
type Claims struct {
EmployeeID int `json:"employee_id"`
jwt.RegisteredClaims
}
// GenerateToken 生成JWT token
func GenerateToken(employeeID int) (string, error) {
claims := Claims{
EmployeeID: employeeID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(config.AppConfig.JWT.ExpireHours) * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(config.AppConfig.JWT.Secret))
}
// ParseToken 解析JWT token
func ParseToken(tokenString string) (*Claims, error) {
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(config.AppConfig.JWT.Secret), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}
// StoreTokenInRedis 将Token存入Redis
func StoreTokenInRedis(ctx context.Context, employeeID int, tokenString string) error {
// Redis key: token:employee:{employeeID}
key := fmt.Sprintf("token:employee:%d", employeeID)
// 存储token过期时间与JWT一致
expiration := time.Duration(config.AppConfig.JWT.ExpireHours) * time.Hour
return SetCache(ctx, key, tokenString, expiration)
}
// ValidateTokenInRedis 验证Token是否在Redis中存在校验是否被禁用
func ValidateTokenInRedis(ctx context.Context, employeeID int, tokenString string) error {
key := fmt.Sprintf("token:employee:%d", employeeID)
// 从Redis获取存储的token
var storedToken string
err := GetCache(ctx, key, &storedToken)
if err != nil {
return errors.New("token已失效或用户已被禁用")
}
// 比对token是否一致
if storedToken != tokenString {
return errors.New("token不匹配用户可能已重新登录")
}
return nil
}
// RevokeToken 撤销Token禁用用户
func RevokeToken(ctx context.Context, employeeID int) error {
key := fmt.Sprintf("token:employee:%d", employeeID)
return DelCache(ctx, key)
}
// RevokeAllUserTokens 撤销用户的所有Token如果有多设备登录
func RevokeAllUserTokens(ctx context.Context, employeeID int) error {
// 当前实现一个用户只保存一个token
// 如果需要支持多设备,可以改为 token:employee:{employeeID}:{deviceID}
return RevokeToken(ctx, employeeID)
}