95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
package jwtx
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"time"
|
||
|
||
"github.com/golang-jwt/jwt/v4"
|
||
)
|
||
|
||
const ExtraKey = "extra"
|
||
|
||
type JwtClaims struct {
|
||
UserId int64 `json:"userId"`
|
||
AgentId int64 `json:"agentId"`
|
||
Platform string `json:"platform"`
|
||
// 用户身份类型:0-临时用户,1-正式用户
|
||
UserType int64 `json:"userType"`
|
||
// 是否代理:0-否,1-是
|
||
IsAgent int64 `json:"isAgent"`
|
||
}
|
||
|
||
// MapToJwtClaims 将 map[string]interface{} 转换为 JwtClaims 结构体
|
||
func MapToJwtClaims(claimsMap map[string]interface{}) (*JwtClaims, error) {
|
||
// 使用JSON序列化/反序列化的方式自动转换
|
||
jsonData, err := json.Marshal(claimsMap)
|
||
if err != nil {
|
||
return nil, errors.New("序列化claims失败")
|
||
}
|
||
|
||
var claims JwtClaims
|
||
if err := json.Unmarshal(jsonData, &claims); err != nil {
|
||
return nil, errors.New("反序列化claims失败")
|
||
}
|
||
|
||
return &claims, nil
|
||
}
|
||
|
||
// GenerateJwtToken 生成JWT token
|
||
func GenerateJwtToken(claims JwtClaims, secret string, expire int64) (string, error) {
|
||
now := time.Now().Unix()
|
||
|
||
// 将 claims 结构体转换为 map[string]interface{}
|
||
claimsBytes, err := json.Marshal(claims)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
var claimsMap map[string]interface{}
|
||
if err := json.Unmarshal(claimsBytes, &claimsMap); err != nil {
|
||
return "", err
|
||
}
|
||
|
||
jwtClaims := jwt.MapClaims{
|
||
"exp": now + expire,
|
||
"iat": now,
|
||
"userId": claims.UserId,
|
||
ExtraKey: claimsMap,
|
||
}
|
||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims)
|
||
return token.SignedString([]byte(secret))
|
||
}
|
||
|
||
func ParseJwtToken(tokenStr string, secret string) (*JwtClaims, error) {
|
||
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
|
||
return []byte(secret), nil
|
||
})
|
||
|
||
if err != nil || !token.Valid {
|
||
return nil, errors.New("invalid JWT")
|
||
}
|
||
|
||
claims, ok := token.Claims.(jwt.MapClaims)
|
||
if !ok || !token.Valid {
|
||
return nil, errors.New("invalid JWT claims")
|
||
}
|
||
|
||
extraInfo, exists := claims[ExtraKey]
|
||
if !exists {
|
||
return nil, errors.New("extra not found in JWT")
|
||
}
|
||
|
||
// 尝试直接断言为 JwtClaims 结构体
|
||
if jwtClaims, ok := extraInfo.(JwtClaims); ok {
|
||
return &jwtClaims, nil
|
||
}
|
||
|
||
// 尝试从 map[string]interface{} 中解析
|
||
if claimsMap, ok := extraInfo.(map[string]interface{}); ok {
|
||
return MapToJwtClaims(claimsMap)
|
||
}
|
||
|
||
return nil, errors.New("unsupported extra type in JWT")
|
||
}
|