2024-01-11 21:57:34 +08:00
|
|
|
package jwtx
|
|
|
|
|
|
|
|
|
|
import (
|
2024-03-23 20:23:08 +08:00
|
|
|
"encoding/json"
|
2024-01-11 21:57:34 +08:00
|
|
|
"errors"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
2024-03-23 20:23:08 +08:00
|
|
|
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!")
|
2024-01-11 21:57:34 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type jwtx struct {
|
2024-03-23 20:23:08 +08:00
|
|
|
SignKey []byte
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Claims struct {
|
2024-03-23 20:23:08 +08:00
|
|
|
UserData string `json:"user_data"`
|
2024-01-11 21:57:34 +08:00
|
|
|
jwt.StandardClaims
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-23 20:23:08 +08:00
|
|
|
func NewJWT(signKey string) *jwtx {
|
2024-01-11 21:57:34 +08:00
|
|
|
return &jwtx{
|
2024-03-23 20:23:08 +08:00
|
|
|
[]byte(signKey),
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 仅解析Token
|
2024-03-23 20:23:08 +08:00
|
|
|
func (j *jwtx) Decode(tokenString string, userData interface{}) error {
|
2024-01-11 21:57:34 +08:00
|
|
|
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
2024-03-23 20:23:08 +08:00
|
|
|
return j.SignKey, nil
|
2024-01-11 21:57:34 +08:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
if ve, ok := err.(*jwt.ValidationError); ok {
|
|
|
|
|
if ve.Errors&jwt.ValidationErrorMalformed == jwt.ValidationErrorMalformed {
|
2024-03-23 20:23:08 +08:00
|
|
|
return ErrTokenMalformed
|
2024-01-11 21:57:34 +08:00
|
|
|
} else if ve.Errors&jwt.ValidationErrorExpired == jwt.ValidationErrorExpired {
|
|
|
|
|
// Token is expired
|
2024-03-23 20:23:08 +08:00
|
|
|
return ErrTokenExpired
|
2024-01-11 21:57:34 +08:00
|
|
|
} else if ve.Errors&jwt.ValidationErrorNotValidYet == jwt.ValidationErrorNotValidYet {
|
2024-03-23 20:23:08 +08:00
|
|
|
return ErrTokenNotValidYet
|
2024-01-11 21:57:34 +08:00
|
|
|
} else {
|
2024-03-23 20:23:08 +08:00
|
|
|
return ErrTokenInvalid
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
claims, ok := token.Claims.(*Claims)
|
|
|
|
|
if !ok || !token.Valid {
|
2024-03-23 20:23:08 +08:00
|
|
|
return ErrTokenInvalid
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
2024-03-23 20:23:08 +08:00
|
|
|
|
|
|
|
|
return json.Unmarshal([]byte(claims.UserData), userData)
|
|
|
|
|
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据参数生成和设置 token
|
2024-03-23 20:23:08 +08:00
|
|
|
func (j *jwtx) Encode(userData interface{}, expiresTime time.Time) (string, error) {
|
2024-01-11 21:57:34 +08:00
|
|
|
|
2024-03-23 20:23:08 +08:00
|
|
|
if expiresTime.Before(time.Now()) {
|
2024-01-11 21:57:34 +08:00
|
|
|
return "", errors.New("时间无效")
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-23 20:23:08 +08:00
|
|
|
db, err := json.Marshal(userData)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", errors.New("json序列化失败")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
claims := Claims{
|
|
|
|
|
UserData: string(db),
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-11 21:57:34 +08:00
|
|
|
// 设置有效时间
|
|
|
|
|
claims.StandardClaims.ExpiresAt = expiresTime.Unix()
|
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
2024-03-23 20:23:08 +08:00
|
|
|
tokenString, err := token.SignedString(j.SignKey)
|
2024-01-11 21:57:34 +08:00
|
|
|
if err != nil {
|
2024-03-23 20:23:08 +08:00
|
|
|
return "", ErrTokenGenerateFailed
|
2024-01-11 21:57:34 +08:00
|
|
|
}
|
|
|
|
|
return tokenString, nil
|
|
|
|
|
}
|