spiderPolyHandler.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package middleware
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. . "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode"
  5. "bp.jydev.jianyu360.cn/BaseService/gateway/common/httpUtil"
  6. "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/filterPoly"
  7. "bp.jydev.jianyu360.cn/BaseService/gateway/core/router"
  8. "bp.jydev.jianyu360.cn/BaseService/gateway/core/util"
  9. "fmt"
  10. "github.com/gogf/gf/v2/frame/g"
  11. "github.com/gogf/gf/v2/net/ghttp"
  12. "github.com/gogf/gf/v2/net/gtrace"
  13. "github.com/gogf/gf/v2/util/gconv"
  14. "net/http"
  15. "strings"
  16. )
  17. const (
  18. defaultVerifyPageHtml = "default"
  19. VerifyPageHtmlSource = "./resources/antiRes/page/%s.html"
  20. JyAntiEncryptSign = "antiEncrypt"
  21. )
  22. var filterPolyManager *filterPoly.Manager
  23. func InitFilterPolyManager() {
  24. filterPolyManager = filterPoly.InitFilterPolyManager()
  25. }
  26. func FilterPolyHandler(r *ghttp.Request) {
  27. func() {
  28. ctx, span := gtrace.NewSpan(r.Context(), "FilterPolyHandler")
  29. defer span.End()
  30. gCtx := router.GetGContext(ctx)
  31. //获取策略
  32. poly := filterPolyManager.GetRule(gCtx.RouterRule.LimitPloy)
  33. status, key := func() (int, string) {
  34. //用户身份切换
  35. userFlag, _ := common.If(gCtx.Sess.MgoUserId != "", gCtx.Sess.MgoUserId, gCtx.Sess.UserId).(string)
  36. if gCtx.Sess.UserId != "" && poly.Rule.BCheckId { //id请求频率校验
  37. return poly.IdFilter(ctx, userFlag)
  38. } else { //ip请求频率校验
  39. return poly.IpFilter(ctx, r.GetClientIp())
  40. }
  41. }()
  42. returnHtml := false
  43. if strings.Contains(strings.ToLower(r.Header.Get("Accept")), "html") {
  44. returnHtml = true
  45. }
  46. //是否开启黑名单
  47. if status == -1 { //黑名单 不响应
  48. r.SetError(NewErrorWithCode(OTHER_ERR_OFTEN, fmt.Sprintf("请求频繁限制")))
  49. r.Response.ResponseWriter.WriteHeader(403)
  50. return
  51. }
  52. if status == 2 { //处理验证码逻辑
  53. rData := poly.VerifyHandle(r.Request, key)
  54. if !returnHtml {
  55. r.Response.WriteJsonExit(rData)
  56. } else {
  57. if renderErr := httpUtil.Render(r.Response.ResponseWriter, getVerifyPage(poly.Rule.VerifyPage), &rData); renderErr != nil {
  58. r.SetError(NewErrorWithCode(GATEWAY_HTML_RENDER_ERR, fmt.Sprintf("验证码页面:%v\n", renderErr)))
  59. }
  60. }
  61. return
  62. }
  63. //处理相应内容加
  64. if poly.Rule.JsEncrypt == 1 {
  65. if !returnHtml {
  66. r.SetCtxVar("changeFunc", SpiderJsEncrypt)
  67. }
  68. }
  69. }()
  70. r.Middleware.Next()
  71. }
  72. // getVerifyPage 获取验证码页面路径
  73. func getVerifyPage(page string) string {
  74. if page != "" {
  75. if strings.HasSuffix(page, ".html") {
  76. page = strings.ReplaceAll(page, ".html", "")
  77. }
  78. return fmt.Sprintf(VerifyPageHtmlSource, page)
  79. } else {
  80. return fmt.Sprintf(VerifyPageHtmlSource, defaultVerifyPageHtml)
  81. }
  82. }
  83. // SpiderJsEncrypt 反爬虫加密相应内容
  84. func SpiderJsEncrypt(resp *http.Response) error {
  85. return util.ChangeResponse(resp, func(bytes []byte) (newBytes []byte, err error) {
  86. if len(bytes) == 0 {
  87. return nil, nil
  88. }
  89. var entryStr string
  90. entryStr, err = util.JyAntiEncrypt(bytes, 9)
  91. if err != nil {
  92. return
  93. }
  94. newBytes = gconv.Bytes(g.Map{
  95. JyAntiEncryptSign: 1,
  96. "data": entryStr,
  97. })
  98. resp.Header.Add(JyAntiEncryptSign, "1")
  99. resp.Header.Add("", "")
  100. return
  101. })
  102. }