package middleware import ( "app.yhyue.com/moapp/jybase/common" log "app.yhyue.com/moapp/jylog" . "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode" "bp.jydev.jianyu360.cn/BaseService/gateway/common/httpUtil" "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/filterPoly" "bp.jydev.jianyu360.cn/BaseService/gateway/core/router" "bp.jydev.jianyu360.cn/BaseService/gateway/core/util" "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/gtrace" "github.com/gogf/gf/v2/util/gconv" "net/http" "strings" ) const ( defaultVerifyPageHtml = "default" VerifyPageHtmlSource = "./resources/antiRes/page/%s.html" JyAntiEncryptSign = "antiEncrypt" JySecretKey = "secretKey" ) var filterPolyManager *filterPoly.Manager func InitFilterPolyManager() { filterPolyManager = filterPoly.InitFilterPolyManager() } func FilterPolyHandler(r *ghttp.Request) { func() { ctx, span := gtrace.NewSpan(r.Context(), "FilterPolyHandler") defer span.End() gCtx := router.GetGContext(ctx) //获取策略 poly := filterPolyManager.GetRule(gCtx.RouterRule.LimitPloy) status, key := func() (int, string) { //用户身份切换 userFlag, _ := common.If(gCtx.Sess.MgoUserId != "", gCtx.Sess.MgoUserId, gCtx.Sess.UserId).(string) if gCtx.Sess.UserId != "" && poly.Rule.BCheckId { //id请求频率校验 return poly.IdFilter(ctx, userFlag) } else { //ip请求频率校验 return poly.IpFilter(ctx, r.GetClientIp()) } }() returnHtml := false if strings.Contains(strings.ToLower(r.Header.Get("Accept")), "html") { returnHtml = true } //是否开启黑名单 if status == -1 { //黑名单 不响应 r.SetError(NewErrorWithCode(OTHER_ERR_OFTEN, fmt.Sprintf("请求频繁限制"))) r.Response.ResponseWriter.WriteHeader(403) return } if status == 2 { //处理验证码逻辑 rData := poly.VerifyHandle(r, key) if !returnHtml { r.Response.WriteJsonExit(rData) } else { if renderErr := httpUtil.Render(r.Response.ResponseWriter, getVerifyPage(poly.Rule.VerifyPage), &rData); renderErr != nil { r.SetError(NewErrorWithCode(GATEWAY_HTML_RENDER_ERR, fmt.Sprintf("验证码页面:%v\n", renderErr))) } } return } //处理相应内容加 if poly.Rule.JsEncrypt == 1 { if !returnHtml { r.SetCtxVar("changeFunc", SpiderJsEncrypt) } } }() r.Middleware.Next() } // getVerifyPage 获取验证码页面路径 func getVerifyPage(page string) string { if page != "" { if strings.HasSuffix(page, ".html") { page = strings.ReplaceAll(page, ".html", "") } return fmt.Sprintf(VerifyPageHtmlSource, page) } else { return fmt.Sprintf(VerifyPageHtmlSource, defaultVerifyPageHtml) } } // SpiderJsEncrypt 反爬虫加密相应内容 func SpiderJsEncrypt(resp *http.Response) error { return util.ChangeResponse(resp, func(bytes []byte) (newBytes []byte, err error) { if len(bytes) == 0 { return nil, nil } var entryStr, PKeyStr string entryStr, PKeyStr, err = util.JyAntiEncrypt(bytes) if err != nil { log.Println("JyAntiEncrypt err: ", err.Error()) return } newBytes = gconv.Bytes(g.Map{ JyAntiEncryptSign: 1, JySecretKey: PKeyStr, "data": entryStr, }) resp.Header.Add(JyAntiEncryptSign, "1") //resp.Header.Add(JySecretKey, PKeyStr) return }) }