commit 07239a2c8c8fa0da92c8d5a5a65b96a895f01577 Author: Yun Date: Thu Jan 11 21:57:34 2024 +0800 提交 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d284078 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module code.yun.ink/pkg/jwtx + +go 1.20 diff --git a/jwtx.go b/jwtx.go new file mode 100644 index 0000000..dec8d39 --- /dev/null +++ b/jwtx.go @@ -0,0 +1,87 @@ +package jwtx + +import ( + "errors" + "time" + + "github.com/dgrijalva/jwt-go" +) + +var ( + TokenExpired error = errors.New("token is expired") + TokenNotValidYet error = errors.New("token not active yet") + TokenMalformed error = errors.New("that's not even a token") + TokenInvalid error = errors.New("couldn't handle this token") + TokenGenerateFailed error = errors.New("generate token failed!") + + // defaultSignKey string = "hcVI@Nm4cjhjPVvCpL5^1%jY" + defaultSignKey = "XiaoXinPlus" + + RedisUserKey string = "user:%d" +) + +type jwtx struct { + SigningKey []byte +} + +type Claims struct { + TenantId int64 `json:"tenant_id"` + ClientId int64 `json:"client_id"` + UserId int64 `json:"user_id"` + + Tag string `json:"tag"` // 额外标记 + + jwt.StandardClaims +} + +func NewJWT() *jwtx { + return &jwtx{ + []byte(defaultSignKey), + } +} + +// 仅解析Token +func (j *jwtx) Decode(tokenString string) (*Claims, error) { + token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { + return j.SigningKey, nil + }) + if err != nil { + if ve, ok := err.(*jwt.ValidationError); ok { + if ve.Errors&jwt.ValidationErrorMalformed == jwt.ValidationErrorMalformed { + return nil, TokenMalformed + } else if ve.Errors&jwt.ValidationErrorExpired == jwt.ValidationErrorExpired { + // Token is expired + return nil, TokenExpired + } else if ve.Errors&jwt.ValidationErrorNotValidYet == jwt.ValidationErrorNotValidYet { + return nil, TokenNotValidYet + } else { + return nil, TokenInvalid + } + } + } + claims, ok := token.Claims.(*Claims) + if !ok || !token.Valid { + return nil, TokenInvalid + } + return claims, nil +} + +// 根据参数生成和设置 token +func (j *jwtx) Encode(claims *Claims, expiresTime time.Time) (string, error) { + + expSecond := expiresTime.Unix() + nowSecond := time.Now().Unix() + + if expSecond-nowSecond < 0 { + return "", errors.New("时间无效") + } + + // 设置有效时间 + claims.StandardClaims.ExpiresAt = expiresTime.Unix() + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + tokenString, err := token.SignedString(j.SigningKey) + if err != nil { + return "", TokenGenerateFailed + } + return tokenString, nil +}