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(), "-", "") }