jwt.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package middleware
  2. import (
  3. "fmt"
  4. "github.com/gin-gonic/gin"
  5. "github.com/go-nunu/nunu-layout/pkg/log"
  6. "github.com/go-nunu/nunu-layout/pkg/resp"
  7. "github.com/golang-jwt/jwt/v5"
  8. "github.com/spf13/viper"
  9. "go.uber.org/zap"
  10. "net/http"
  11. "regexp"
  12. )
  13. type JWT struct {
  14. key string
  15. }
  16. type MyCustomClaims struct {
  17. UserId int64
  18. jwt.RegisteredClaims
  19. }
  20. // NewJwt https://pkg.go.dev/github.com/golang-jwt/jwt/v5
  21. func NewJwt(conf *viper.Viper) *JWT {
  22. return &JWT{key: conf.GetString("security.jwt.key")}
  23. }
  24. func (j *JWT) GenToken() string {
  25. token := jwt.NewWithClaims(jwt.SigningMethodHS512, MyCustomClaims{
  26. UserId: 1,
  27. })
  28. // Sign and get the complete encoded token as a string using the key
  29. tokenString, err := token.SignedString(j.key)
  30. fmt.Println(tokenString, err)
  31. return tokenString
  32. }
  33. func (j *JWT) ParseToken(tokenString string) (*MyCustomClaims, error) {
  34. re, _ := regexp.Compile(`(?i)Bearer `)
  35. tokenString = re.ReplaceAllString(tokenString, "")
  36. token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
  37. return []byte("AllYourBase"), nil
  38. })
  39. if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
  40. return claims, nil
  41. } else {
  42. return nil, err
  43. }
  44. }
  45. func NoAuth(log *log.Logger) gin.HandlerFunc {
  46. return func(ctx *gin.Context) {
  47. log.WithGinContext(ctx).Info("建立请求")
  48. ctx.Next()
  49. }
  50. }
  51. // StrictAuth 严格权限
  52. func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
  53. return func(ctx *gin.Context) {
  54. tokenString := ctx.Request.Header.Get("Authorization")
  55. if tokenString == "" {
  56. log.WithGinContext(ctx).Warn("请求未携带token,无权限访问", zap.Any("data", map[string]interface{}{
  57. "url": ctx.Request.URL,
  58. "params": ctx.Params,
  59. }))
  60. resp.HandleError(ctx, http.StatusUnauthorized, 1, "no token", nil)
  61. ctx.Abort()
  62. return
  63. }
  64. // parseToken 解析token包含的信息
  65. claims, err := j.ParseToken(tokenString)
  66. if err != nil {
  67. log.WithGinContext(ctx).Error("token error", zap.Any("data", map[string]interface{}{
  68. "url": ctx.Request.URL,
  69. "params": ctx.Params,
  70. }))
  71. resp.HandleError(ctx, http.StatusUnauthorized, 1, err.Error(), nil)
  72. ctx.Abort()
  73. return
  74. }
  75. // 继续交由下一个路由处理,并将解析出的信息传递下去
  76. ctx.Set("claims", claims)
  77. recoveryLoggerFunc(ctx, log)
  78. ctx.Next()
  79. }
  80. }
  81. func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
  82. return func(ctx *gin.Context) {
  83. tokenString := ctx.Request.Header.Get("Authorization")
  84. if tokenString == "" {
  85. tokenString, _ = ctx.Cookie("accessToken")
  86. }
  87. if tokenString == "" {
  88. tokenString = ctx.Query("accessToken")
  89. }
  90. if tokenString == "" {
  91. log.WithGinContext(ctx).Info("建立请求")
  92. ctx.Next()
  93. return
  94. }
  95. // parseToken 解析token包含的信息
  96. claims, err := j.ParseToken(tokenString)
  97. if err != nil {
  98. log.WithGinContext(ctx).Info("建立请求")
  99. ctx.Next()
  100. return
  101. }
  102. // 继续交由下一个路由处理,并将解析出的信息传递下去
  103. ctx.Set("claims", claims)
  104. recoveryLoggerFunc(ctx, log)
  105. ctx.Next()
  106. }
  107. }
  108. func recoveryLoggerFunc(ctx *gin.Context, logger *log.Logger) {
  109. if ctx.Request.URL.Path == "/cos/object" && ctx.Request.Method == "POST" {
  110. return
  111. }
  112. userInfo := ctx.MustGet("claims").(*MyCustomClaims)
  113. logger.NewGinContext(ctx, zap.Int64("UserId", userInfo.UserId))
  114. logger.WithGinContext(ctx).Info("建立请求")
  115. // 统计
  116. }