package middleware import ( "fmt" "net/url" "sort" "strings" "surveyService/response" "surveyService/util" "surveyService/util/constants" "github.com/gin-gonic/gin" "gogs.uu.mdfitnesscao.com/hys/sdk" "gogs.uu.mdfitnesscao.com/hys/sdk/mechanism" ) func AuthorizeMechanismByAppKey() gin.HandlerFunc { return func(c *gin.Context) { appKey := c.Request.Header.Get("appkey") if appKey == "" { response.Fail(c, response.ErrInvalidToken) return } sign := c.Request.Header.Get("sign") if sign == "" { response.Fail(c, response.ErrSign) return } var currentUser *sdk.AuthMechanism var err *response.ErrCode // 拿到用户系统的资料 detailResponse, findErr := mechanism.DetailByAppKey(appKey) if findErr != nil { response.Fail(c, &response.ErrCode{ Code: response.INVALID_TOKEN, Msg: findErr.Msg, }) return } currentUser = &sdk.AuthMechanism{ ID: detailResponse.Data.Detail.ID, Nickname: detailResponse.Data.Detail.Nickname, Account: detailResponse.Data.Detail.Account, LoginAt: 0, IsMechanism: true, FullPermission: false, Permissions: detailResponse.Data.Detail.Permissions, Mechanism: &sdk.AuthBaseMechanism{ ID: detailResponse.Data.Detail.ID, Nickname: detailResponse.Data.Detail.Nickname, Account: detailResponse.Data.Detail.Account, RawId: detailResponse.Data.Detail.RawId, AppKey: detailResponse.Data.Detail.AppKey, AppSecret: detailResponse.Data.Detail.AppSecret, IpWhiteList: detailResponse.Data.Detail.IpWhiteList, CallbackUrlList: detailResponse.Data.Detail.CallbackUrlList, }, } if err != nil { response.Fail(c, err) return } // 校验签名 requestData := util.GetRequestJsonData(c) makedSign := makeSign(requestData, currentUser.Mechanism.AppSecret) // fmt.Println(makedSign, sign) if makedSign != sign { response.Fail(c, response.ErrSign) return } c.Set(constants.MechanismOpenAPICacheKey, currentUser) c.Next() } } func makeSign(requestData map[string]any, appSecret string) string { // 将map的key存储到一个切片中 keys := make([]string, 0, len(requestData)) for k := range requestData { keys = append(keys, k) } // 对切片进行排序 sort.Strings(keys) // 将请求参数按照key的升序排列 var requestDataArray []string = make([]string, 0) // 遍历排序后的切片,并使用map的key来访问map中的值 for _, k := range keys { v := requestData[k] requestDataArray = append(requestDataArray, k+"="+url.QueryEscape(fmt.Sprint(v))) } // 拼接成key1=value1&key2=value2&key3=value3的形式 requestDataString := strings.Join(requestDataArray, "&") // fmt.Println("拼装后字段", requestDataString) // 将appSecret拼接到最后 signString := requestDataString + appSecret // fmt.Println("待签名字段", signString) // 计算md5 sign := strings.ToUpper(util.Md5(signString)) // fmt.Println("签名: ", sign) return sign }