package utils import ( "fmt" "time" "github.com/golang-jwt/jwt/v5" "golang.org/x/crypto/bcrypt" ) // JWTClaims JWT声明结构体 type JWTClaims struct { UserID uint `json:"user_id"` Username string `json:"username"` IsAdmin bool `json:"is_admin"` jwt.RegisteredClaims } // GenerateToken 生成JWT令牌 func GenerateToken(userID uint, username string, isAdmin bool, secretKey string, expireTime time.Duration) (string, error) { // 创建声明 claims := JWTClaims{ UserID: userID, Username: username, IsAdmin: isAdmin, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(expireTime)), IssuedAt: jwt.NewNumericDate(time.Now()), NotBefore: jwt.NewNumericDate(time.Now()), }, } // 创建令牌 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 签名令牌 tokenString, err := token.SignedString([]byte(secretKey)) if err != nil { return "", err } return tokenString, nil } // ParseToken 解析JWT令牌 func ParseToken(tokenString string, secretKey string) (*JWTClaims, error) { // 解析令牌 token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) { // 验证签名方法 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(secretKey), nil }) if err != nil { return nil, err } // 验证令牌并获取声明 if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid { return claims, nil } return nil, fmt.Errorf("invalid token") } // HashPassword 密码加密 func HashPassword(password string) (string, error) { hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return "", err } return string(hash), nil } // VerifyPassword 密码验证 func VerifyPassword(hashedPassword, password string) error { return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) } // GenerateRandomString 生成随机字符串 func GenerateRandomString(length int) string { const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" randomBytes := make([]byte, length) for i := range randomBytes { randomBytes[i] = charset[time.Now().UnixNano()%int64(len(charset))] } return string(randomBytes) }