package jwt import ( "dy-admin/pkg/comopts" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v4" "github.com/pkg/errors" "time" ) var ( TokenExpired = errors.New("Token is expired") TokenNotValidYet = errors.New("Token not active yet") TokenMalformed = errors.New("That's not even a token") TokenInvalid = errors.New("Couldn't handle this token:") ) type CustomClaims struct { BaseClaims jwt.RegisteredClaims } type BaseClaims struct { UUID string UserID int Username string NickName string RoleIDs []int DeptID int RoleNames []string } type JWT struct { options *comopts.JwtOptions } func NewJWT(opt *comopts.JwtOptions) *JWT { return &JWT{ options: opt, } } func (j *JWT) CreateClaims(baseClaims BaseClaims) CustomClaims { claims := CustomClaims{ BaseClaims: baseClaims, RegisteredClaims: jwt.RegisteredClaims{ NotBefore: jwt.NewNumericDate(time.Now()), // 签名生效时间 ExpiresAt: jwt.NewNumericDate(time.Now().Add(j.options.Timeout)), // 过期时间 7天 配置文件 Issuer: j.options.Realm, // 签名的发行者 }, } return claims } func (j *JWT) CreateToken(claims CustomClaims) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(j.options.Key)) } //func (j *JWT) CreateTokenByOldToken(oldToken string, claims CustomClaims) (string, error) { // v, err, _ := global.ConcurrencyControl.Do("JWT:"+oldToken, func() (interface{}, error) { // return j.CreateToken(claims) // }) // return v.(string), err //} func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) { token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) { return []byte(j.options.Key), nil }) if err != nil { if ve, ok := err.(*jwt.ValidationError); ok { if ve.Errors&jwt.ValidationErrorMalformed != 0 { return nil, TokenMalformed } else if ve.Errors&jwt.ValidationErrorExpired != 0 { // Token is expired return nil, TokenExpired } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { return nil, TokenNotValidYet } else { return nil, TokenInvalid } } } if token != nil { if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid { return claims, nil } return nil, TokenInvalid } else { return nil, TokenInvalid } } func (j *JWT) GetClaims(c *gin.Context) (*CustomClaims, error) { token := c.Request.Header.Get("Authorization") claims, err := j.ParseToken(token) if err != nil { return nil, err } return claims, err } func (j *JWT) GetUserID(c *gin.Context) int { if claims, exists := c.Get("claims"); !exists { if cl, err := j.GetClaims(c); err != nil { return 0 } else { return cl.UserID } } else { waitUse := claims.(*CustomClaims) return waitUse.UserID } } func (j *JWT) GetDeptID(c *gin.Context) int { if claims, exists := c.Get("claims"); !exists { if cl, err := j.GetClaims(c); err != nil { return 0 } else { return cl.DeptID } } else { waitUse := claims.(*CustomClaims) return waitUse.DeptID } } func (j *JWT) GetUserRoleIDs(c *gin.Context) []int { if claims, exists := c.Get("claims"); !exists { if cl, err := j.GetClaims(c); err != nil { return []int{} } else { return cl.RoleIDs } } else { waitUse := claims.(*CustomClaims) return waitUse.RoleIDs } } func (j *JWT) GetUserInfo(c *gin.Context) *CustomClaims { if claims, exists := c.Get("claims"); !exists { if cl, err := j.GetClaims(c); err != nil { return nil } else { return cl } } else { waitUse := claims.(*CustomClaims) return waitUse } }