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.

138 lines
3.0 KiB

  1. package middleware
  2. import (
  3. "errors"
  4. "github.com/dgrijalva/jwt-go"
  5. "github.com/gin-gonic/gin"
  6. uuid "github.com/satori/go.uuid"
  7. "net/http"
  8. "time"
  9. )
  10. func JWTAuth() gin.HandlerFunc {
  11. return func(c *gin.Context) {
  12. token := c.Request.Header.Get("x-token")
  13. if token == "" {
  14. c.JSON(http.StatusOK, gin.H{
  15. "success": false,
  16. "msg": "未登录或非法访问",
  17. "data": gin.H{},
  18. })
  19. c.Abort()
  20. return
  21. }
  22. j := NewJWT()
  23. // parseToken 解析token包含的信息
  24. claims, err := j.ParseToken(token)
  25. if err != nil {
  26. if err == TokenExpired {
  27. c.JSON(http.StatusOK, gin.H{
  28. "success": false,
  29. "msg": "授权已过期",
  30. })
  31. c.Abort()
  32. return
  33. }
  34. c.JSON(http.StatusOK, gin.H{
  35. "success": false,
  36. "msg": err.Error(),
  37. })
  38. c.Abort()
  39. return
  40. }
  41. c.Set("claims", claims)
  42. }
  43. }
  44. type JWT struct {
  45. SigningKey []byte
  46. }
  47. var (
  48. TokenExpired error = errors.New("Token is expired")
  49. TokenNotValidYet error = errors.New("Token not active yet")
  50. TokenMalformed error = errors.New("That's not even a token")
  51. TokenInvalid error = errors.New("Couldn't handle this token:")
  52. SignKey string = "newtrekWang"
  53. )
  54. type CustomClaims struct {
  55. UUID uuid.UUID
  56. ID uint
  57. AuthorityID uint
  58. jwt.StandardClaims
  59. }
  60. func NewJWT() *JWT {
  61. return &JWT{
  62. []byte(GetSignKey()),
  63. }
  64. }
  65. //获取token
  66. func GetSignKey() string {
  67. return SignKey
  68. }
  69. // 这是SignKey
  70. func SetSignKey(key string) string {
  71. SignKey = key
  72. return SignKey
  73. }
  74. //创建一个token
  75. func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
  76. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  77. return token.SignedString(j.SigningKey)
  78. }
  79. //解析 token
  80. func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
  81. token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
  82. return j.SigningKey, nil
  83. })
  84. if err != nil {
  85. if ve, ok := err.(*jwt.ValidationError); ok {
  86. if ve.Errors&jwt.ValidationErrorMalformed != 0 {
  87. return nil, TokenMalformed
  88. } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
  89. // Token is expired
  90. return nil, TokenExpired
  91. } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
  92. return nil, TokenNotValidYet
  93. } else {
  94. return nil, TokenInvalid
  95. }
  96. }
  97. }
  98. if token != nil {
  99. if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
  100. return claims, nil
  101. }
  102. return nil, TokenInvalid
  103. } else {
  104. return nil, TokenInvalid
  105. }
  106. }
  107. // 更新token
  108. func (j *JWT) RefreshToken(tokenString string) (string, error) {
  109. jwt.TimeFunc = func() time.Time {
  110. return time.Unix(0, 0)
  111. }
  112. token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
  113. return j.SigningKey, nil
  114. })
  115. if err != nil {
  116. return "", err
  117. }
  118. if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
  119. jwt.TimeFunc = time.Now
  120. claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
  121. return j.CreateToken(*claims)
  122. }
  123. return "", TokenInvalid
  124. }