'init'
This commit is contained in:
101
sc-lktx-backend/internal/common/utils/jwt.go
Normal file
101
sc-lktx-backend/internal/common/utils/jwt.go
Normal file
@@ -0,0 +1,101 @@
|
||||
// JWT Token 生成与解析 + 业务工具函数
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// JWTClaims JWT 载荷,包含用户 ID 和角色列表
|
||||
type JWTClaims struct {
|
||||
UserID uint `json:"user_id"`
|
||||
RoleCode string `json:"role_code"` // 角色(visitor/employee/guard)
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// AdminJWTClaims 管理员 JWT 载荷
|
||||
type AdminJWTClaims struct {
|
||||
AdminID uint `json:"admin_id"`
|
||||
Account string `json:"account"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// GenerateAdminToken 生成管理员 JWT
|
||||
func GenerateAdminToken(adminID uint, account string, secret string, expireHours int) (string, error) {
|
||||
claims := AdminJWTClaims{
|
||||
AdminID: adminID,
|
||||
Account: account,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expireHours) * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: "lktx-admin",
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(secret))
|
||||
}
|
||||
|
||||
// ParseAdminToken 解析管理员 JWT
|
||||
func ParseAdminToken(tokenString string, secret string) (*AdminJWTClaims, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &AdminJWTClaims{}, 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(secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if claims, ok := token.Claims.(*AdminJWTClaims); ok && token.Valid {
|
||||
return claims, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
// GenerateToken 生成 JWT(单角色,兼容旧版)
|
||||
func GenerateToken(userID uint, roleCode string, secret string, expireHours int) (string, error) {
|
||||
claims := JWTClaims{
|
||||
UserID: userID,
|
||||
RoleCode: roleCode,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expireHours) * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: "lktx-mp",
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(secret))
|
||||
}
|
||||
|
||||
// ParseToken 解析并验证 JWT
|
||||
func ParseToken(tokenString string, secret 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(secret), 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")
|
||||
}
|
||||
|
||||
// GenerateInviteCode 生成 16 位随机邀请码
|
||||
func GenerateInviteCode() string {
|
||||
b := make([]byte, 8)
|
||||
rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
// GenerateQRCodeContent 生成二维码内容
|
||||
func GenerateQRCodeContent(appointmentID uint) string {
|
||||
return fmt.Sprintf("LKTX:APPT:%d:%d", appointmentID, time.Now().Unix())
|
||||
}
|
||||
Reference in New Issue
Block a user