spiderPolyHandler.go 3.4 KB

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