You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.9 KiB

  1. package utils
  2. import (
  3. "errors"
  4. "github.com/dgrijalva/jwt-go"
  5. "github.com/flipped-aurora/gin-vue-admin/server/global"
  6. "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
  7. )
  8. type JWT struct {
  9. SigningKey []byte
  10. }
  11. var (
  12. TokenExpired = errors.New("Token is expired")
  13. TokenNotValidYet = errors.New("Token not active yet")
  14. TokenMalformed = errors.New("That's not even a token")
  15. TokenInvalid = errors.New("Couldn't handle this token:")
  16. )
  17. func NewJWT() *JWT {
  18. return &JWT{
  19. []byte(global.GVA_CONFIG.JWT.SigningKey),
  20. }
  21. }
  22. // 创建一个token
  23. func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
  24. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  25. return token.SignedString(j.SigningKey)
  26. }
  27. // CreateTokenByOldToken 旧token 换新token 使用归并回源避免并发问题
  28. func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.CustomClaims) (string, error) {
  29. v, err, _ := global.GVA_Concurrency_Control.Do("JWT:"+oldToken, func() (interface{}, error) {
  30. return j.CreateToken(claims)
  31. })
  32. return v.(string), err
  33. }
  34. // 解析 token
  35. func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) {
  36. token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
  37. return j.SigningKey, nil
  38. })
  39. if err != nil {
  40. if ve, ok := err.(*jwt.ValidationError); ok {
  41. if ve.Errors&jwt.ValidationErrorMalformed != 0 {
  42. return nil, TokenMalformed
  43. } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
  44. // Token is expired
  45. return nil, TokenExpired
  46. } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
  47. return nil, TokenNotValidYet
  48. } else {
  49. return nil, TokenInvalid
  50. }
  51. }
  52. }
  53. if token != nil {
  54. if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid {
  55. return claims, nil
  56. }
  57. return nil, TokenInvalid
  58. } else {
  59. return nil, TokenInvalid
  60. }
  61. }