auth.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package middleware
  2. import (
  3. "crypto/md5"
  4. "errors"
  5. "eta_gn/eta_bridge/controller/resp"
  6. "eta_gn/eta_bridge/global"
  7. "eta_gn/eta_bridge/models/crm"
  8. "eta_gn/eta_bridge/utils"
  9. "fmt"
  10. "github.com/gin-gonic/gin"
  11. "math"
  12. "sort"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. func BaseAuthCheck() gin.HandlerFunc {
  18. return func(c *gin.Context) {
  19. method := c.Request.Method
  20. if method != "POST" {
  21. resp.TokenError(nil, "请求异常", "不支持非POST请求", c)
  22. c.Abort()
  23. return
  24. }
  25. pass, e := signCheck(c)
  26. if e != nil {
  27. resp.TokenError(nil, "签名错误", "签名校验失败, Err: "+e.Error(), c)
  28. c.Abort()
  29. return
  30. }
  31. if !pass {
  32. resp.TokenError(nil, "签名错误", "签名错误", c)
  33. c.Abort()
  34. return
  35. }
  36. }
  37. }
  38. func signCheck(c *gin.Context) (ok bool, err error) {
  39. params := make(map[string][]string)
  40. err = c.ShouldBind(params)
  41. if err != nil {
  42. return
  43. }
  44. signData := convertParam(params)
  45. ip := c.ClientIP()
  46. err = checkSignData(signData, ip)
  47. if err != nil {
  48. return
  49. }
  50. ok = true
  51. return
  52. }
  53. func convertParam(params map[string][]string) (signData map[string]string) {
  54. signData = make(map[string]string)
  55. for key := range params {
  56. signData[key] = params[key][0]
  57. }
  58. return signData
  59. }
  60. func checkSignData(postData map[string]string, ip string) (err error) {
  61. isSandbox := postData["is_sandbox"]
  62. if global.CONFIG.Serve.RunMode == "debug" && isSandbox != "" {
  63. return
  64. }
  65. appid := postData["appid"]
  66. if appid == "" {
  67. err = errors.New("参数异常,缺少appid")
  68. return
  69. }
  70. openApiOB := new(crm.OpenApiUser)
  71. apiUser, e := openApiOB.GetItemByAppid(appid)
  72. if e != nil {
  73. if e != utils.ErrNoRow {
  74. err = errors.New("系统异常,请联系管理员")
  75. return
  76. }
  77. err = errors.New("appid异常,请联系管理员")
  78. return
  79. }
  80. if apiUser == nil {
  81. err = errors.New("系统异常,请联系管理员")
  82. return
  83. }
  84. if apiUser.Ip != "" {
  85. if !strings.Contains(apiUser.Ip, ip) {
  86. err = errors.New(fmt.Sprintf("无权限访问该接口,ip:%v,请联系管理员", ip))
  87. return
  88. }
  89. }
  90. ownSign := postData["sign"]
  91. if ownSign == "" {
  92. err = errors.New("参数异常,缺少签名字符串")
  93. return
  94. }
  95. if postData["nonce_str"] == "" {
  96. err = errors.New("参数异常,缺少随机字符串")
  97. return
  98. }
  99. if postData["timestamp"] == "" {
  100. err = errors.New("参数异常,缺少时间戳")
  101. return
  102. } else {
  103. timeUnix := time.Now().Unix() // 当前格林威治时间,int64类型
  104. timestamp, timeErr := strconv.ParseInt(postData["timestamp"], 10, 64)
  105. if timeErr != nil {
  106. err = errors.New("参数异常,时间戳格式异常")
  107. return
  108. }
  109. if math.Abs(float64(timeUnix-timestamp)) > 300 {
  110. err = errors.New("当前时间异常,请调整设备时间与北京时间一致")
  111. return
  112. }
  113. }
  114. var keys []string
  115. for k := range postData {
  116. if k != "sign" {
  117. keys = append(keys, k)
  118. }
  119. }
  120. sort.Strings(keys)
  121. var signStr string
  122. for _, v := range keys {
  123. signStr += v + "=" + postData[v] + "&"
  124. }
  125. sign := strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(signStr+"secret="+apiUser.Secret))))
  126. if sign != ownSign {
  127. global.LOG.Info(fmt.Sprintf("签名校验异常,签名字符串:%v;服务端签名值:%v", signStr, sign))
  128. return errors.New("签名校验异常,请核实签名")
  129. }
  130. return nil
  131. }