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 }