// Copyright 2020 github.com. All rights reserved. // Use of this source code is governed by github.com. package middleware import ( "git.getensh.com/common/gopkgs/jwtwrapper" "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" "github.com/tidwall/gjson" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "net/http" "property-system-gateway/errors" "property-system-gateway/utils" "strconv" "strings" ) // 响应数据 type Response struct { Code codes.Code `json:"code" default:"1"` Message string `json:"message" default:"success"` } // JWT is jwt middleware func Jwt() gin.HandlerFunc { return func(c *gin.Context) { //fmt.Printf("xxx:%v,%v\n", c.Request.RequestURI, c.Request.Method) s := status.New(1, "内部服务错误") token := c.GetHeader("token") if token == "" { if v, ok := status.FromError(errors.NoTokenError); ok { s = v } c.JSON(http.StatusOK, Response{s.Code(), s.Message()}) c.Abort() return } // 解析token claims, err := jwtwrapper.ParseToken(token) if err != nil { switch err.(*jwt.ValidationError).Errors { case jwt.ValidationErrorExpired: if v, ok := status.FromError(errors.TokenExpiredError); ok { s = v } default: if v, ok := status.FromError(errors.TokenFailedError); ok { s = v } } c.JSON(http.StatusOK, Response{s.Code(), s.Message()}) c.Abort() return } // 将claims信息保存到上下文,为后续使用 c.Set("claims", claims) gardenId := gjson.GetBytes([]byte(claims.Subject), "garden_id").Int() uid, _ := strconv.ParseInt(claims.Id, 10, 64) cid := gjson.GetBytes([]byte(claims.Subject), "cid").Int() /* supper := gjson.GetBytes(utils.StrToBytes(claims.Subject), "supper").Bool() if c.Request.Method == "PUT" || c.Request.Method == "POST" || c.Request.Method == "DELETE" { if supper == false && strings.Contains(c.Request.RequestURI, "/user") == false { c.JSON(http.StatusOK, Response{10008, "权限不足"}) } } */ isCompanyEnter := gjson.GetBytes([]byte(claims.Subject), "is_company_enter").Bool() if isCompanyEnter && !strings.Contains(c.Request.RequestURI, "user/company_login") { c.JSON(http.StatusOK, Response{10010, "token错误"}) c.Abort() return } if isCompanyEnter && strings.Contains(c.Request.RequestURI, "user/company_login") { c.Next() return } if uid == 0 && !strings.Contains(c.Request.RequestURI, "user/choose_user") { c.JSON(http.StatusOK, Response{10008, "请先选择账户"}) c.Abort() return } gPermissionTime := gjson.GetBytes([]byte(claims.Subject), "g_permission_time").String() uPermissionTime := gjson.GetBytes([]byte(claims.Subject), "u_permission_time").String() byCompany := gjson.GetBytes([]byte(claims.Subject), "by_company").Bool() // 权限变更触发重新登录 if gardenId > 0 && gPermissionTime != gloablePermissionTime(gardenId) { if strings.Contains(c.Request.RequestURI, "permission_reget") { c.Next() return } c.JSON(http.StatusOK, Response{19999, "权限已变更重新获取权限"}) c.Abort() return } if !byCompany && uPermissionTime != userPermissionTime(uid) { if strings.Contains(c.Request.RequestURI, "permission_reget") { c.Next() return } c.JSON(http.StatusOK, Response{19999, "权限已变更重新获取权限"}) c.Abort() return } // 单点登录检查 if false { singleSignTime := gjson.GetBytes([]byte(claims.Subject), "single_sign_time").String() if singleSignTime != utils.GetSingleSignTime(utils.GetSingleFlag(byCompany, cid, gardenId, uid)) && !strings.Contains(c.Request.RequestURI, "user/choose_user") && !strings.Contains(c.Request.RequestURI, "user/company_login") { c.JSON(http.StatusOK, Response{10008, "账号已在其他地方登录"}) c.Abort() return } } // 权限检查 TODO 目前暂时放开,后续需检查权限 super := gjson.GetBytes([]byte(claims.Subject), "is_super_group").Bool() if super { //c.Next() //return } if byCompany { //c.Next() //return } if c.Request.Method == "GET" { c.Next() return } if strings.Contains(c.Request.RequestURI, "openim") { c.Next() return } routers := gjson.GetBytes([]byte(claims.Subject), "routers").Map() err = checkPermission(routers, c.Request.RequestURI, uid, gPermissionTime, uPermissionTime) if err != nil { if v, ok := status.FromError(err); ok { s = v } c.JSON(http.StatusOK, Response{s.Code(), s.Message()}) c.Abort() return } c.Next() } }