From c1a6b191b4b3ffc9749976e974a1c1e4c511e903 Mon Sep 17 00:00:00 2001
From: liujiandao <274878379@qq.com>
Date: 星期五, 03 十一月 2023 14:57:59 +0800
Subject: [PATCH] 添加登录验证

---
 constvar/const.go   |    8 ++
 request/jwt.go      |   20 +++++
 go.sum              |    2 
 middleware/utils.go |   60 +++++++++++++++
 middleware/jwt.go   |  101 +++++-------------------
 go.mod              |    1 
 docs/swagger.yaml   |    2 
 docs/docs.go        |    3 
 docs/swagger.json   |    3 
 router/router.go    |    1 
 10 files changed, 123 insertions(+), 78 deletions(-)

diff --git a/constvar/const.go b/constvar/const.go
index a84fd10..ff95383 100644
--- a/constvar/const.go
+++ b/constvar/const.go
@@ -191,3 +191,11 @@
 	RuleType_Product         RuleType = iota + 1 //浜у搧涓婃灦瑙勫垯
 	RuleType_ProductCategory                     //浜у搧绫诲埆涓婃灦瑙勫垯
 )
+
+type UserType int
+
+const (
+	UserTypeSuper   UserType = iota + 1 // 瓒呯骇绠$悊鍛�
+	UserTypePrimary                     // 涓昏处鎴�
+	UserTypeSub                         // 瀛愯处鎴�
+)
diff --git a/docs/docs.go b/docs/docs.go
index 575933f..fe9c170 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -3489,6 +3489,9 @@
                     "description": "姣忛〉澶у皬",
                     "type": "integer"
                 },
+                "productId": {
+                    "type": "string"
+                },
                 "type": {
                     "description": "绫诲瀷:bh=琛ヨ揣",
                     "type": "string"
diff --git a/docs/swagger.json b/docs/swagger.json
index 16eff99..53621ab 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -3477,6 +3477,9 @@
                     "description": "姣忛〉澶у皬",
                     "type": "integer"
                 },
+                "productId": {
+                    "type": "string"
+                },
                 "type": {
                     "description": "绫诲瀷:bh=琛ヨ揣",
                     "type": "string"
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index c318180..d15fc23 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -949,6 +949,8 @@
       pageSize:
         description: 姣忛〉澶у皬
         type: integer
+      productId:
+        type: string
       type:
         description: 绫诲瀷:bh=琛ヨ揣
         type: string
diff --git a/go.mod b/go.mod
index b409b36..371244a 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@
 	basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/gin-gonic/gin v1.9.0
+	github.com/golang-jwt/jwt/v4 v4.5.0
 	github.com/google/uuid v1.3.1
 	github.com/nsqio/go-nsq v1.1.0
 	github.com/open-policy-agent/opa v0.57.1
diff --git a/go.sum b/go.sum
index a038626..a602140 100644
--- a/go.sum
+++ b/go.sum
@@ -140,6 +140,8 @@
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
diff --git a/middleware/jwt.go b/middleware/jwt.go
index 48686f2..d9d7dd4 100644
--- a/middleware/jwt.go
+++ b/middleware/jwt.go
@@ -1,94 +1,39 @@
 package middleware
 
 import (
-	"errors"
-	"fmt"
-	"strings"
-	"time"
-	"wms/conf"
-
-	jwt "github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
-	"wms/extend/util"
+	"strings"
+	"wms/pkg/contextx"
+	"wms/pkg/ecode"
 )
 
-func validateToken(tokenString string) (util.JSON, error) {
-	secretKey := []byte(conf.WebConf.JWTSecret)
-
-	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
-		// Don't forget to validate the alg is what you expect:
-		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
-			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
-		}
-
-		return secretKey, nil
-	})
-
-	if err != nil {
-		return util.JSON{}, err
-	}
-
-	if !token.Valid {
-		return util.JSON{}, errors.New("invalid token")
-	}
-
-	return token.Claims.(jwt.MapClaims), nil
-}
-
-// JWTMiddleware parses JWT token from cookie and stores data and expires date to the context
-// JWT Token can be passed as cookie, or Authorization header
-func JWTMiddleware() gin.HandlerFunc {
+func JWTAuth() gin.HandlerFunc {
 	return func(c *gin.Context) {
-		tokenString, err := c.Cookie("token")
-		// failed to read cookie
-		if err != nil {
-			// try reading HTTP Header
-			authorization := c.Request.Header.Get("Authorization")
-			if authorization == "" {
-				c.Next()
-				return
-			}
-			sp := strings.Split(authorization, "Bearer ")
-			// invalid token
-			if len(sp) < 1 {
-				c.Next()
-				return
-			}
-			tokenString = sp[1]
+		ctx := new(contextx.Context).SetCtx(c)
+		// 鎴戜滑杩欓噷jwt閴存潈鍙栧ご閮ㄤ俊鎭� Authorization 鐧诲綍鏃跺洖杩斿洖token淇℃伅 杩欓噷鍓嶇闇�瑕佹妸token瀛樺偍鍒癱ookie鎴栬�呮湰鍦發ocalStorage涓� 涓嶈繃闇�瑕佽窡鍚庣鍗忓晢杩囨湡鏃堕棿 鍙互绾﹀畾鍒锋柊浠ょ墝鎴栬�呴噸鏂扮櫥褰�
+		token := c.Request.Header.Get("Authorization")
+		if token == "" {
+			ctx.Fail(ecode.JWTEmpty)
+			c.Abort()
+			return
 		}
-
-		tokenData, err := validateToken(tokenString)
+		slices := strings.Split(token, " ")
+		if len(slices) == 2 {
+			token = slices[1]
+		}
+		j := NewJWT()
+		// parseToken 瑙f瀽token鍖呭惈鐨勪俊鎭�
+		claims, err := j.ParseToken(token)
 		if err != nil {
-			fmt.Println(err.Error())
+			if err == TokenExpired {
+				c.Next()
+				return
+			}
 			c.Next()
 			return
 		}
 
-		userParentId := tokenData["parentId"].(string)
-		if userParentId == conf.WebConf.NodeId {
-			c.Set("parentId", userParentId)
-		} else {
-			c.Next()
-			return
-		}
-
-		c.Set("token_expire", tokenData["exp"])
+		c.Set("claims", claims)
 		c.Next()
 	}
-}
-
-func GenerateToken(data interface{}) (string, error) {
-	//  token is valid for 1 hour
-	date := time.Now().Add(time.Hour * 12)
-
-	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
-		"user": data,
-		"exp":  date.Unix(),
-	})
-
-	secretKey := []byte(conf.WebConf.JWTSecret)
-
-	tokenString, err := token.SignedString(secretKey)
-
-	return tokenString, err
 }
diff --git a/middleware/utils.go b/middleware/utils.go
new file mode 100644
index 0000000..58defa0
--- /dev/null
+++ b/middleware/utils.go
@@ -0,0 +1,60 @@
+package middleware
+
+import (
+	"errors"
+	"github.com/golang-jwt/jwt/v4"
+	"wms/request"
+)
+
+type JWT struct {
+	SigningKey []byte
+}
+
+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:")
+)
+
+func NewJWT() *JWT {
+	return &JWT{
+		[]byte("327a9457-899a-481e-8b30-58cc97e5b808"),
+	}
+}
+
+// CreateToken 鍒涘缓涓�涓猼oken
+func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	return token.SignedString(j.SigningKey)
+}
+
+// ParseToken 瑙f瀽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) {
+		return j.SigningKey, 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.(*request.CustomClaims); ok && token.Valid {
+			return claims, nil
+		}
+		return nil, TokenInvalid
+
+	} else {
+		return nil, TokenInvalid
+	}
+}
diff --git a/request/jwt.go b/request/jwt.go
new file mode 100644
index 0000000..dece0f1
--- /dev/null
+++ b/request/jwt.go
@@ -0,0 +1,20 @@
+package request
+
+import (
+	"github.com/dgrijalva/jwt-go"
+	"wms/constvar"
+)
+
+// Custom claims structure
+type CustomClaims struct {
+	BaseClaims
+	BufferTime int64
+	jwt.StandardClaims
+}
+
+type BaseClaims struct {
+	UserId   string
+	Username string
+	ParentId string
+	UserType constvar.UserType
+}
diff --git a/router/router.go b/router/router.go
index 7d527e8..b4dac9f 100644
--- a/router/router.go
+++ b/router/router.go
@@ -20,6 +20,7 @@
 	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
 
 	urlPrefix := "/api-wms/v1"
+	r.Use(middleware.JWTAuth())
 
 	// 缁勭粐绠$悊
 	departmentController := new(controllers.DepartmentController)

--
Gitblit v1.8.0