package middlewares import ( "crypto/hmac" "crypto/sha1" "encoding/hex" "fmt" "github.com/gin-gonic/gin" "hospital-open-api/api/dao" "hospital-open-api/api/responses" "hospital-open-api/consts" "net/http" "net/url" "sort" "strings" ) // Auth Auth认证 func Auth() gin.HandlerFunc { return func(c *gin.Context) { appId := c.Request.Header.Get("appId") if appId == "" { c.JSON(http.StatusUnauthorized, gin.H{ "message": "请求未授权", "code": consts.TokenError, "data": "", }) c.Abort() return } sign := c.Request.Header.Get("sign") if sign == "" { c.JSON(http.StatusUnauthorized, gin.H{ "message": "缺少签名", "code": consts.TokenError, "data": "", }) c.Abort() return } // 获取开放数据 openKeyDao := dao.OpenKeyDao{} openKey, err := openKeyDao.GetOpenKeyByDoctorId(appId) if err != nil || openKey == nil { responses.FailWithMessage("非法appId", c) c.Abort() return } if openKey.Status != 1 { responses.FailWithMessage("非法appId", c) c.Abort() return } paramsRaw, ok := c.Get("params") if !ok { c.JSON(http.StatusInternalServerError, gin.H{ "message": "Invalid params type", "code": consts.ServerError, "data": "", }) c.Abort() return } concatenatedParamsStr := "" requestParams, ok := paramsRaw.(map[string]string) if ok || len(requestParams) > 0 { // 将请求参数按照参数名升序排序 sortedKeys := make([]string, 0, len(requestParams)) for key := range requestParams { sortedKeys = append(sortedKeys, key) } sort.Strings(sortedKeys) // 按照参数名=参数值的格式拼接参数 var concatenatedParams []string for _, key := range sortedKeys { value := url.QueryEscape(requestParams[key]) // 对参数值进行 URL 编码 concatenatedParams = append(concatenatedParams, fmt.Sprintf("%s=%s", key, value)) } concatenatedParamsStr = strings.Join(concatenatedParams, "&") } h := hmac.New(sha1.New, []byte(openKey.AppSecret)) h.Write([]byte(concatenatedParamsStr)) signature := hex.EncodeToString(h.Sum(nil)) fmt.Println(signature) if signature == "" { responses.FailWithMessage("签名错误", c) c.Abort() return } // 检测签名 if signature != sign { responses.FailWithMessage("签名错误", c) c.Abort() return } c.Next() } }