Files
servicebase/pkg/secure/jwt.go
2025-11-19 14:24:13 +08:00

87 lines
2.6 KiB
Go

package secure
import (
"crypto/ecdsa"
"strings"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
type Claims struct {
Username string `json:"un,omitempty"`
Nickname string `json:"nn,omitempty"`
ExtID string `json:"ei,omitempty"`
jwt.RegisteredClaims
}
func (c Claims) NeedRefresh(d time.Duration) bool {
return c.ExpiresAt.Before(time.Now().Add(d))
}
func GenerateToken(iss, uid, username, nickname string, exp, nbf, iat time.Time, aud []string, primaryKey string) (tokenStr string, e error) {
token := jwt.NewWithClaims(jwt.SigningMethodES256, &Claims{
Username: username,
Nickname: nickname,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: iss, // 令牌发行者
Subject: uid, // 统一用户ID
Audience: aud, // 受众
ExpiresAt: &jwt.NumericDate{Time: exp}, // 过期时间
NotBefore: &jwt.NumericDate{Time: nbf}, // 启用时间
IssuedAt: &jwt.NumericDate{Time: iat}, // 发布时间
ID: JwtID(), // jwt ID
},
})
var ecdsaKey *ecdsa.PrivateKey
if ecdsaKey, e = jwt.ParseECPrivateKeyFromPEM([]byte(primaryKey)); e != nil {
panic(e)
}
tokenStr, e = token.SignedString(ecdsaKey)
return
}
func GenerateTokenWithEID(iss, uid, username, nickname, eid string, exp, nbf, iat time.Time, aud []string, primaryKey string) (tokenStr string, e error) {
token := jwt.NewWithClaims(jwt.SigningMethodES256, &Claims{
Username: username,
Nickname: nickname,
ExtID: eid,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: iss, // 令牌发行者
Subject: uid, // 统一用户ID
Audience: aud, // 受众
ExpiresAt: &jwt.NumericDate{Time: exp}, // 过期时间
NotBefore: &jwt.NumericDate{Time: nbf}, // 启用时间
IssuedAt: &jwt.NumericDate{Time: iat}, // 发布时间
ID: JwtID(), // jwt ID
},
})
var ecdsaKey *ecdsa.PrivateKey
if ecdsaKey, e = jwt.ParseECPrivateKeyFromPEM([]byte(primaryKey)); e != nil {
panic(e)
}
tokenStr, e = token.SignedString(ecdsaKey)
return
}
func VerifyToken(tokenStr, publicKey string) (access bool, claims Claims, e error) {
var ecdsaKeyPub *ecdsa.PublicKey
if ecdsaKeyPub, e = jwt.ParseECPublicKeyFromPEM([]byte(publicKey)); e != nil {
return
}
var token *jwt.Token
if token, e = jwt.ParseWithClaims(tokenStr, &claims, func(token *jwt.Token) (any, error) {
return ecdsaKeyPub, nil
}); e != nil {
return
}
access = token.Valid
return
}
func JwtID() string {
u4 := uuid.New()
return strings.ReplaceAll(u4.String(), "-", "")
}