98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package jwt
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
jwtv5 "github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
var (
|
|
ErrTokenValid = errors.New("未知错误")
|
|
ErrTokenExpired = errors.New("token已过期")
|
|
ErrTokenNotValidYet = errors.New("token尚未激活")
|
|
ErrTokenMalformed = errors.New("这不是一个token")
|
|
ErrTokenSignatureInvalid = errors.New("无效签名")
|
|
ErrTokenInvalid = errors.New("无法处理此token")
|
|
)
|
|
|
|
// BaseClaims 基础Claims
|
|
type BaseClaims struct {
|
|
ID string `json:"id"`
|
|
Account string `json:"account"`
|
|
}
|
|
|
|
// CustomClaims 自定义Claims
|
|
type CustomClaims struct {
|
|
BaseClaims
|
|
BufferTime int64 `json:"bufferTime"`
|
|
jwtv5.RegisteredClaims
|
|
}
|
|
|
|
// JWT JWT工具
|
|
type JWT struct {
|
|
SigningKey []byte
|
|
}
|
|
|
|
// NewJWT 创建JWT实例
|
|
func NewJWT(signingKey string) *JWT {
|
|
return &JWT{
|
|
SigningKey: []byte(signingKey),
|
|
}
|
|
}
|
|
|
|
// CreateClaims 创建Claims
|
|
func (j *JWT) CreateClaims(baseClaims BaseClaims, bufferTime, expiresTime time.Duration, issuer string) CustomClaims {
|
|
return CustomClaims{
|
|
BaseClaims: baseClaims,
|
|
BufferTime: int64(bufferTime / time.Second),
|
|
RegisteredClaims: jwtv5.RegisteredClaims{
|
|
Audience: jwtv5.ClaimStrings{"sundynix"},
|
|
NotBefore: jwtv5.NewNumericDate(time.Now().Add(-1000)),
|
|
ExpiresAt: jwtv5.NewNumericDate(time.Now().Add(expiresTime)),
|
|
Issuer: issuer,
|
|
},
|
|
}
|
|
}
|
|
|
|
// CreateToken 创建token
|
|
func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
|
|
token := jwtv5.NewWithClaims(jwtv5.SigningMethodHS256, claims)
|
|
return token.SignedString(j.SigningKey)
|
|
}
|
|
|
|
// ParseToken 解析token
|
|
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
|
|
token, err := jwtv5.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwtv5.Token) (interface{}, error) {
|
|
return j.SigningKey, nil
|
|
})
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, jwtv5.ErrTokenExpired):
|
|
return nil, ErrTokenExpired
|
|
case errors.Is(err, jwtv5.ErrTokenNotValidYet):
|
|
return nil, ErrTokenNotValidYet
|
|
case errors.Is(err, jwtv5.ErrTokenMalformed):
|
|
return nil, ErrTokenMalformed
|
|
case errors.Is(err, jwtv5.ErrTokenSignatureInvalid):
|
|
return nil, ErrTokenSignatureInvalid
|
|
default:
|
|
return nil, ErrTokenInvalid
|
|
}
|
|
}
|
|
if token != nil {
|
|
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
|
|
return claims, nil
|
|
}
|
|
}
|
|
return nil, ErrTokenInvalid
|
|
}
|
|
|
|
// GetTokenFromHeader 从Authorization头中提取token
|
|
func GetTokenFromHeader(authHeader string) string {
|
|
if len(authHeader) > 7 && authHeader[:7] == "Bearer " {
|
|
return authHeader[7:]
|
|
}
|
|
return authHeader
|
|
}
|