96 lines
2.7 KiB
Go
96 lines
2.7 KiB
Go
package token
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.apinb.com/bsm-sdk/core/errcode"
|
|
"git.apinb.com/bsm-sdk/core/vars"
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
type Claims struct {
|
|
ID uint `json:"id"`
|
|
Identity string `json:"identity"`
|
|
Extend map[string]string `json:"extend"`
|
|
Client string `json:"client"`
|
|
Owner any `json:"owner"`
|
|
Role string `json:"role"`
|
|
jwt.RegisteredClaims // v5版本新加的方法
|
|
}
|
|
|
|
type tokenJwt struct {
|
|
SecretKey string
|
|
}
|
|
|
|
func New(secretKey string) *tokenJwt {
|
|
return &tokenJwt{SecretKey: secretKey}
|
|
}
|
|
|
|
// 生成JWT
|
|
func (t *tokenJwt) GenerateJwt(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) {
|
|
keyLen := len(t.SecretKey)
|
|
if !(keyLen == 16 || keyLen == 24 || keyLen == 32) {
|
|
return "", errcode.ErrTokenSecretKey
|
|
}
|
|
|
|
now := time.Now()
|
|
|
|
claims := Claims{
|
|
ID: id,
|
|
Identity: identity,
|
|
Client: client,
|
|
Extend: extend,
|
|
Owner: owner,
|
|
Role: role,
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(now.Add(vars.JwtExpire)), // 过期时间24小时
|
|
IssuedAt: jwt.NewNumericDate(now), // 签发时间
|
|
NotBefore: jwt.NewNumericDate(now), // 生效时间
|
|
},
|
|
}
|
|
// 使用HS256签名算法
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
s, err := token.SignedString([]byte(t.SecretKey))
|
|
return s, errcode.String(errcode.ErrTokenGenerate, err.Error())
|
|
}
|
|
|
|
// 解析JWT
|
|
func (t *tokenJwt) ParseJwt(tokenstring string) (*Claims, error) {
|
|
token, err := jwt.ParseWithClaims(tokenstring, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
|
return []byte(t.SecretKey), nil
|
|
})
|
|
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
|
return claims, nil
|
|
} else {
|
|
return nil, errcode.String(errcode.ErrTokenParse, err.Error())
|
|
}
|
|
}
|
|
|
|
// 验证JWT是否过期
|
|
func (t *tokenJwt) IsExpired(tokenstring string) (bool, error) {
|
|
// 分割JWT的三个部分
|
|
parts := strings.Split(tokenstring, ".")
|
|
if len(parts) != 3 {
|
|
return false, errcode.ErrTokenDataInvalid
|
|
}
|
|
|
|
// 解码Payload部分
|
|
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
|
if err != nil {
|
|
return false, errcode.String(errcode.ErrTokenBase64Decode, err.Error())
|
|
}
|
|
|
|
// 解析JSON
|
|
var claims jwt.RegisteredClaims
|
|
if err := json.Unmarshal(payload, &claims); err != nil {
|
|
return false, errcode.String(errcode.ErrTokenJsonDecode, err.Error())
|
|
}
|
|
|
|
// 检查过期时间
|
|
currentTime := time.Now().Unix()
|
|
return claims.ExpiresAt.Unix() < currentTime, nil
|
|
}
|