2023-09-04 15:35:49 +08:00

108 lines
2.4 KiB
Go

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()
}
}