check_signature.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package interceptor
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/xinliangnote/go-gin-api/configs"
  6. "github.com/xinliangnote/go-gin-api/internal/code"
  7. "github.com/xinliangnote/go-gin-api/internal/pkg/core"
  8. "github.com/xinliangnote/go-gin-api/internal/repository/mysql/authorized"
  9. "github.com/xinliangnote/go-gin-api/pkg/env"
  10. "github.com/xinliangnote/go-gin-api/pkg/errors"
  11. "github.com/xinliangnote/go-gin-api/pkg/signature"
  12. "github.com/xinliangnote/go-gin-api/pkg/urltable"
  13. )
  14. var whiteListPath = map[string]bool{
  15. "/login/web": true,
  16. }
  17. func (i *interceptor) CheckSignature() core.HandlerFunc {
  18. return func(c core.Context) {
  19. if !env.Active().IsPro() {
  20. return
  21. }
  22. // 签名信息
  23. authorization := c.GetHeader(configs.HeaderSignToken)
  24. if authorization == "" {
  25. c.AbortWithError(core.Error(
  26. http.StatusBadRequest,
  27. code.AuthorizationError,
  28. code.Text(code.AuthorizationError)).WithError(errors.New("Header 中缺少 Authorization 参数")),
  29. )
  30. return
  31. }
  32. // 时间信息
  33. date := c.GetHeader(configs.HeaderSignTokenDate)
  34. if date == "" {
  35. c.AbortWithError(core.Error(
  36. http.StatusBadRequest,
  37. code.AuthorizationError,
  38. code.Text(code.AuthorizationError)).WithError(errors.New("Header 中缺少 Date 参数")),
  39. )
  40. return
  41. }
  42. // 通过签名信息获取 key
  43. authorizationSplit := strings.Split(authorization, " ")
  44. if len(authorizationSplit) < 2 {
  45. c.AbortWithError(core.Error(
  46. http.StatusBadRequest,
  47. code.AuthorizationError,
  48. code.Text(code.AuthorizationError)).WithError(errors.New("Header 中 Authorization 格式错误")),
  49. )
  50. return
  51. }
  52. key := authorizationSplit[0]
  53. data, err := i.authorizedService.DetailByKey(c, key)
  54. if err != nil {
  55. c.AbortWithError(core.Error(
  56. http.StatusBadRequest,
  57. code.AuthorizationError,
  58. code.Text(code.AuthorizationError)).WithError(err),
  59. )
  60. return
  61. }
  62. if data.IsUsed == authorized.IsUsedNo {
  63. c.AbortWithError(core.Error(
  64. http.StatusBadRequest,
  65. code.AuthorizationError,
  66. code.Text(code.AuthorizationError)).WithError(errors.New(key + " 已被禁止调用")),
  67. )
  68. return
  69. }
  70. if len(data.Apis) < 1 {
  71. c.AbortWithError(core.Error(
  72. http.StatusBadRequest,
  73. code.AuthorizationError,
  74. code.Text(code.AuthorizationError)).WithError(errors.New(key + " 未进行接口授权")),
  75. )
  76. return
  77. }
  78. if !whiteListPath[c.Path()] {
  79. // 验证 c.Method() + c.Path() 是否授权
  80. table := urltable.NewTable()
  81. for _, v := range data.Apis {
  82. _ = table.Append(v.Method + v.Api)
  83. }
  84. if pattern, _ := table.Mapping(c.Method() + c.Path()); pattern == "" {
  85. c.AbortWithError(core.Error(
  86. http.StatusBadRequest,
  87. code.AuthorizationError,
  88. code.Text(code.AuthorizationError)).WithError(errors.New(c.Method() + c.Path() + " 未进行接口授权")),
  89. )
  90. return
  91. }
  92. }
  93. ok, err := signature.New(key, data.Secret, configs.HeaderSignTokenTimeout).Verify(authorization, date, c.Path(), c.Method(), c.RequestInputParams())
  94. if err != nil {
  95. c.AbortWithError(core.Error(
  96. http.StatusBadRequest,
  97. code.AuthorizationError,
  98. code.Text(code.AuthorizationError)).WithError(err),
  99. )
  100. return
  101. }
  102. if !ok {
  103. c.AbortWithError(core.Error(
  104. http.StatusBadRequest,
  105. code.AuthorizationError,
  106. code.Text(code.AuthorizationError)).WithError(errors.New("Header 中 Authorization 信息错误")),
  107. )
  108. return
  109. }
  110. }
  111. }