From b68185aed1a86536b01fdfbca6b2cca7bd71a50f Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期六, 23 三月 2024 17:12:18 +0800
Subject: [PATCH] 增加token验证和数据权限过滤
---
middleware/jwt.go | 113 +++++-------------
utils/jwt/claims.go | 62 ++++++++++
conf/config.go | 16 +-
controllers/order.go | 66 ++++++++++
models/outsourcing_order.go | 9 +
conf/config.yaml | 1
utils/jwt/jwt.go | 63 ++++++++++
router/router.go | 2
8 files changed, 238 insertions(+), 94 deletions(-)
diff --git a/conf/config.go b/conf/config.go
index a8f58ac..3201a3d 100644
--- a/conf/config.go
+++ b/conf/config.go
@@ -23,14 +23,14 @@
type (
webConf struct {
- Host string // 鏈満ip鍦板潃
- Port string // 绔彛鍙�
- APPort string // 鏈満浣滀负鐨凣rpc鏈嶅姟绔殑绔彛鍙�
- AlHost string // 绠楁硶鏈嶅姟ip鍦板潃
- AlPort string // 绠楁硶鏈嶅姟绔彛鍙�
- NodeId string // 涓昏处鎴风敤鎴峰悕
- OssType string // 瀵硅薄瀛樺偍绫诲瀷
- JWTSecret string
+ Host string // 鏈満ip鍦板潃
+ Port string // 绔彛鍙�
+ APPort string // 鏈満浣滀负鐨凣rpc鏈嶅姟绔殑绔彛鍙�
+ AlHost string // 绠楁硶鏈嶅姟ip鍦板潃
+ AlPort string // 绠楁硶鏈嶅姟绔彛鍙�
+ NodeId string // 涓昏处鎴风敤鎴峰悕
+ OssType string // 瀵硅薄瀛樺偍绫诲瀷
+ JWTKey string
}
nsqConf struct {
diff --git a/conf/config.yaml b/conf/config.yaml
index 2e0d467..37c133c 100644
--- a/conf/config.yaml
+++ b/conf/config.yaml
@@ -1,6 +1,7 @@
web:
port: 8008
host: 192.168.20.119
+ jwtKey: 12345
service:
aps: 192.168.20.120:9091
db:
diff --git a/controllers/order.go b/controllers/order.go
index f627704..c527cf1 100644
--- a/controllers/order.go
+++ b/controllers/order.go
@@ -13,6 +13,7 @@
"outsourcing/request"
"outsourcing/service"
"outsourcing/service/outsourcing"
+ "outsourcing/utils/jwt"
)
type OrderController struct{}
@@ -30,7 +31,14 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
return
}
- list, total, err := models.NewOutsourcingOrderSearch().SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetOrder("id desc").Find()
+
+ companyId := jwt.GetCompanyID(c)
+ if companyId == 0 {
+ util.ResponseFormat(c, code.InternalError, "鍐呴儴閿欒")
+ return
+ }
+
+ list, total, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(companyId).SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetOrder("id desc").Find()
if err != nil {
util.ResponseFormat(c, code.InternalError, "鏌ヨ閿欒")
return
@@ -45,7 +53,7 @@
// @Success 200 {object} util.ResponseList{data=request.OutsourcingOrderOverview} "鎴愬姛"
// @Router /api-outsourcing/v1/order/overview [get]
func (slf *OrderController) OrderOverview(c *gin.Context) {
- result, err := models.NewOutsourcingOrderSearch().CountGroupByStatus()
+ result, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).CountGroupByStatus()
if err != nil {
util.ResponseFormat(c, code.InternalError, "鏌ヨ閿欒")
return
@@ -80,6 +88,13 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟缂哄け")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderId).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
list, total, err := models.NewOutsourcingOrderProductSearch().SetPage(params.Page, params.PageSize).SetOutsourcingOrderID(params.OutsourcingOrderId).SetOrder("id desc").Find()
if err != nil {
util.ResponseFormat(c, code.InternalError, "鏌ヨ閿欒")
@@ -105,8 +120,15 @@
util.ResponseFormat(c, code.RequestParamError, "鐗╂枡鐢宠涓嶈兘涓虹┖")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.ApplyList[0].OutsourcingOrderNumber).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
var apply []*models.OutsourcingMaterialApply
- err := structx.AssignTo(params.ApplyList, &apply)
+ err = structx.AssignTo(params.ApplyList, &apply)
if err != nil {
util.ResponseFormat(c, code.RequestParamError, "鏁版嵁杞崲澶辫触")
return
@@ -141,6 +163,13 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.Number).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
find, err := models.NewOutsourcingMaterialApplySearch().SetOutsourcingOrderNumber(params.Number).FindNotTotal()
if err != nil {
util.ResponseFormat(c, code.RequestParamError, "鏌ヨ澶辫触")
@@ -162,6 +191,13 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.OutsourcingOrderNumber).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
//闄愬畾鐘舵�佸弬鏁�
if params.Status == constvar.OutsourcingOrderStatusCreate || //鍙栨秷纭
params.Status == constvar.OutsourcingOrderStatusWaitProduce || //纭鎺ュ彈
@@ -196,6 +232,12 @@
}
if params.OutsourcingOrderID == 0 {
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟缂哄け")
+ return
+ }
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
return
}
@@ -236,6 +278,13 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟缂哄け")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
if len(params.DeliveryList) == 0 {
util.ResponseFormat(c, code.RequestParamError, "鍙戣揣鍒楄〃涓嶈兘涓虹┖")
return
@@ -248,8 +297,8 @@
WaybillNumber: params.WaybillNumber,
}
- err := models.WithTransaction(func(db *gorm.DB) error {
- err := models.NewOutsourcingOrderDeliverySearch().SetOrm(db).Create(delivery)
+ err = models.WithTransaction(func(db *gorm.DB) error {
+ err = models.NewOutsourcingOrderDeliverySearch().SetOrm(db).Create(delivery)
if err != nil {
return err
}
@@ -285,6 +334,13 @@
util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
return
}
+
+ _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "璁㈠崟涓嶅瓨鍦�")
+ return
+ }
+
list, err := models.NewOutsourcingOrderDeliveryDetailsSearch().
SetOutsourcingOrderID(params.OutsourcingOrderID).
SetPreload(true).
diff --git a/middleware/jwt.go b/middleware/jwt.go
index f67fc8a..520f651 100644
--- a/middleware/jwt.go
+++ b/middleware/jwt.go
@@ -1,94 +1,47 @@
package middleware
import (
- "errors"
- "fmt"
- "outsourcing/conf"
- "strings"
- "time"
-
- jwt "github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
- "outsourcing/extend/util"
+ "outsourcing/conf"
+ "outsourcing/pkg/contextx"
+ "outsourcing/pkg/ecode"
+ "outsourcing/utils/jwt"
+ "strings"
)
-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]
- }
-
- tokenData, err := validateToken(tokenString)
- if err != nil {
- fmt.Println(err.Error())
- c.Next()
+ 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
}
-
- userParentId := tokenData["parentId"].(string)
- if userParentId == conf.WebConf.NodeId {
- c.Set("parentId", userParentId)
- } else {
- c.Next()
+ slices := strings.Split(token, " ")
+ if len(slices) == 2 {
+ token = slices[1]
+ }
+ j := jwt.NewOutsideJWT(conf.WebConf.JWTKey)
+ // parseToken 瑙f瀽token鍖呭惈鐨勪俊鎭�
+ claims, err := j.ParseToken(token)
+ if err != nil {
+ if err == jwt.TokenExpired {
+ ctx.Fail(ecode.JWTExpire)
+ c.Abort()
+ return
+ }
+ ctx.Fail(ecode.JWTParseErr)
+ c.Abort()
return
}
-
- c.Set("token_expire", tokenData["exp"])
+ if claims.CompanyId == 0 {
+ ctx.Fail(ecode.JWTExpire)
+ c.Abort()
+ return
+ }
+ 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/models/outsourcing_order.go b/models/outsourcing_order.go
index 8ab108c..11e19cd 100644
--- a/models/outsourcing_order.go
+++ b/models/outsourcing_order.go
@@ -65,6 +65,11 @@
return slf
}
+func (slf *OutsourcingOrderSearch) SetEnterpriseID(id uint) *OutsourcingOrderSearch {
+ slf.EnterpriseID = id
+ return slf
+}
+
func (slf *OutsourcingOrderSearch) SetIDs(ids []uint) *OutsourcingOrderSearch {
slf.IDs = ids
return slf
@@ -96,6 +101,10 @@
db = db.Where("id = ?", slf.ID)
}
+ if slf.EnterpriseID != 0 {
+ db = db.Where("enterprise_id = ?", slf.EnterpriseID)
+ }
+
if len(slf.IDs) != 0 {
db = db.Where("id in ?", slf.IDs)
}
diff --git a/router/router.go b/router/router.go
index a9e935e..1bb46fe 100644
--- a/router/router.go
+++ b/router/router.go
@@ -22,7 +22,7 @@
urlPrefix := "/api-outsourcing/v1"
outsourcingApi := new(controllers.OrderController)
- outsourcingGroup := r.Group(urlPrefix + "/order")
+ outsourcingGroup := r.Group(urlPrefix + "/order").Use(middleware.JWTAuth())
{
outsourcingGroup.GET("list", outsourcingApi.OutsourcingOrderList) // 濮斿璁㈠崟鍒楄〃
outsourcingGroup.GET("overview", outsourcingApi.OrderOverview) // 濮斿璁㈠崟缁熻
diff --git a/utils/jwt/claims.go b/utils/jwt/claims.go
new file mode 100644
index 0000000..26c5dad
--- /dev/null
+++ b/utils/jwt/claims.go
@@ -0,0 +1,62 @@
+package jwt
+
+import (
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+ "outsourcing/conf"
+ "outsourcing/pkg/logx"
+ "strings"
+)
+
+type OutsideUserClaims struct {
+ UserId string
+ Username string
+ ParentId string
+ CompanyId uint
+ CompanyName string
+ BufferTime int64
+ jwt.StandardClaims
+}
+
+func GetClaims(c *gin.Context) (*OutsideUserClaims, error) {
+ token := c.Request.Header.Get("Authorization")
+ logx.Infof("GetClaims token:%v", token)
+ slices := strings.Split(token, " ")
+ if len(slices) == 2 {
+ token = slices[1]
+ }
+ j := NewOutsideJWT(conf.WebConf.JWTKey)
+ claims, err := j.ParseToken(token)
+ if err != nil {
+ logx.Error("浠嶨in鐨凜ontext涓幏鍙栦粠jwt瑙f瀽淇℃伅澶辫触, 璇锋鏌ヨ姹傚ご鏄惁瀛樺湪x-token涓攃laims鏄惁涓鸿瀹氱粨鏋�")
+ }
+ return claims, err
+}
+
+// GetCompanyID 浠嶨in鐨凜ontext涓幏鍙栦粠jwt瑙f瀽鍑烘潵鐨勫叕鍙窱D
+func GetCompanyID(c *gin.Context) uint {
+ if claims, exists := c.Get("claims"); !exists {
+ if cl, err := GetClaims(c); err != nil {
+ return 0
+ } else {
+ return cl.CompanyId
+ }
+ } else {
+ waitUse := claims.(*OutsideUserClaims)
+ return waitUse.CompanyId
+ }
+}
+
+// GetUserInfo 浠嶨in鐨凜ontext涓幏鍙栦粠jwt瑙f瀽鍑烘潵鐨勭敤鎴蜂俊鎭�
+func GetUserInfo(c *gin.Context) *OutsideUserClaims {
+ if claims, exists := c.Get("claims"); !exists {
+ if cl, err := GetClaims(c); err != nil {
+ return nil
+ } else {
+ return cl
+ }
+ } else {
+ waitUse := claims.(*OutsideUserClaims)
+ return waitUse
+ }
+}
diff --git a/utils/jwt/jwt.go b/utils/jwt/jwt.go
new file mode 100644
index 0000000..8e01128
--- /dev/null
+++ b/utils/jwt/jwt.go
@@ -0,0 +1,63 @@
+package jwt
+
+import (
+ "errors"
+ "github.com/dgrijalva/jwt-go"
+)
+
+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:")
+)
+
+type OutSideJWT struct {
+ SigningKey []byte
+}
+
+func NewOutsideJWT(signKey string) *OutSideJWT {
+ return &OutSideJWT{
+ []byte(signKey),
+ }
+}
+
+// CreateToken 鍒涘缓涓�涓猼oken
+func (j *OutSideJWT) CreateToken(claims OutsideUserClaims) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ return token.SignedString(j.SigningKey)
+}
+
+// ParseToken 瑙f瀽token
+func (j *OutSideJWT) ParseToken(tokenString string) (*OutsideUserClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &OutsideUserClaims{}, 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.(*OutsideUserClaims); ok && token.Valid {
+ return claims, nil
+ }
+ return nil, TokenInvalid
+
+ } else {
+ return nil, TokenInvalid
+ }
+}
--
Gitblit v1.8.0