package jwtx import ( "encoding/json" "errors" "time" "github.com/dgrijalva/jwt-go" ) var ( ErrTokenExpired error = errors.New("token is expired") ErrTokenNotValidYet error = errors.New("token not active yet") ErrTokenMalformed error = errors.New("that's not even a token") ErrTokenInvalid error = errors.New("couldn't handle this token") ErrTokenGenerateFailed error = errors.New("generate token failed!") ) type jwtx struct { SignKey []byte } type Claims struct { UserData string `json:"user_data"` jwt.StandardClaims } func NewJWT(signKey string) *jwtx { return &jwtx{ []byte(signKey), } } // 仅解析Token func (j *jwtx) Decode(tokenString string, userData interface{}) error { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { return j.SignKey, nil }) if err != nil { if ve, ok := err.(*jwt.ValidationError); ok { if ve.Errors&jwt.ValidationErrorMalformed == jwt.ValidationErrorMalformed { return ErrTokenMalformed } else if ve.Errors&jwt.ValidationErrorExpired == jwt.ValidationErrorExpired { // Token is expired return ErrTokenExpired } else if ve.Errors&jwt.ValidationErrorNotValidYet == jwt.ValidationErrorNotValidYet { return ErrTokenNotValidYet } else { return ErrTokenInvalid } } } claims, ok := token.Claims.(*Claims) if !ok || !token.Valid { return ErrTokenInvalid } return json.Unmarshal([]byte(claims.UserData), userData) } // 根据参数生成和设置 token func (j *jwtx) Encode(userData interface{}, expiresTime time.Time) (string, error) { if expiresTime.Before(time.Now()) { return "", errors.New("时间无效") } db, err := json.Marshal(userData) if err != nil { return "", errors.New("json序列化失败") } claims := Claims{ UserData: string(db), } // 设置有效时间 claims.StandardClaims.ExpiresAt = expiresTime.Unix() token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString(j.SignKey) if err != nil { return "", ErrTokenGenerateFailed } return tokenString, nil }