Files
2024-03-23 20:23:08 +08:00

87 lines
2.1 KiB
Go

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
}