Переглянути джерело

Merge pull request #566 from songzhibin97/gva_gormv2_dev

feat:增加singleFlight并发控制jwt颁发
奇淼(piexlmax 3 роки тому
батько
коміт
a5fea14f56
3 змінених файлів з 18 додано та 5 видалено
  1. 5 2
      server/global/global.go
  2. 1 0
      server/go.mod
  3. 12 3
      server/middleware/jwt.go

+ 5 - 2
server/global/global.go

@@ -3,6 +3,8 @@ package global
 import (
 	"gin-vue-admin/utils/timer"
 
+	"golang.org/x/sync/singleflight"
+
 	"go.uber.org/zap"
 
 	"gin-vue-admin/config"
@@ -18,6 +20,7 @@ var (
 	GVA_CONFIG config.Server
 	GVA_VP     *viper.Viper
 	//GVA_LOG    *oplogging.Logger
-	GVA_LOG   *zap.Logger
-	GVA_Timer timer.Timer = timer.NewTimerTask()
+	GVA_LOG                 *zap.Logger
+	GVA_Timer               timer.Timer = timer.NewTimerTask()
+	GVA_Concurrency_Control             = &singleflight.Group{}
 )

+ 1 - 0
server/go.mod

@@ -51,6 +51,7 @@ require (
 	github.com/unrolled/secure v1.0.7
 	go.uber.org/zap v1.10.0
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
+	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
 	golang.org/x/tools v0.0.0-20200324003944-a576cf524670 // indirect
 	google.golang.org/protobuf v1.24.0 // indirect
 	gopkg.in/ini.v1 v1.55.0 // indirect

+ 12 - 3
server/middleware/jwt.go

@@ -7,11 +7,12 @@ import (
 	"gin-vue-admin/model/request"
 	"gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"strconv"
+	"time"
+
 	"github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
 	"go.uber.org/zap"
-	"strconv"
-	"time"
 )
 
 func JWTAuth() gin.HandlerFunc {
@@ -48,7 +49,7 @@ func JWTAuth() gin.HandlerFunc {
 		}
 		if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
 			claims.ExpiresAt = time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime
-			newToken, _ := j.CreateToken(*claims)
+			newToken, _ := j.CreateTokenByOldToken(token, *claims)
 			newClaims, _ := j.ParseToken(newToken)
 			c.Header("new-token", newToken)
 			c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
@@ -91,6 +92,14 @@ func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
 	return token.SignedString(j.SigningKey)
 }
 
+// CreateTokenByOldToken 旧token 换新token 使用归并回源避免并发问题
+func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.CustomClaims) (string, error) {
+	v, err, _ := global.GVA_Concurrency_Control.Do("JWT:"+oldToken, func() (interface{}, error) {
+		return j.CreateToken(claims)
+	})
+	return v.(string), err
+}
+
 // 解析 token
 func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) {
 	token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {