core/crypto/token/jwt.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
}