From 7216b0ea8c8ba15bf75d887602072d78fe16d894 Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Tue, 29 Sep 2026 13:56:45 +0800 Subject: [PATCH] =?UTF-8?q?OCR=20=E4=BB=A3=E7=90=86=E9=80=8F=E4=BC=A0?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E5=AE=A2=E6=88=B7=E7=AB=AF=20IP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端按 IP 对匿名付费的 OCR 接口限流,而这个 route 原本只带 TenantId,后端 IpUtil 只能拿到 Nuxt 服务器的出口 IP——限流会退化成「整个官网共用一份配额」,正常用户 反而被误限;而 H5 是浏览器直连后端、能拿到真实 IP,同一策略两条链路行为相反。 用仓库里现成的 getRealClientIp(event)(server/utils/ip.ts,form/submit.post.ts 已在用)取真实 IP 并透传 X-Forwarded-For。只加这一个 header,租户解析、query、 返回值解包与错误包装都未改动。 --- server/api/tender/ocr/recognize.post.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/api/tender/ocr/recognize.post.ts b/server/api/tender/ocr/recognize.post.ts index 3836b6b..2f85ee0 100644 --- a/server/api/tender/ocr/recognize.post.ts +++ b/server/api/tender/ocr/recognize.post.ts @@ -2,6 +2,7 @@ import { $fetch } from 'ofetch' import { createError, defineEventHandler, readBody } from 'h3' import { useRuntimeConfig } from '#imports' import { getTenantFromContext } from '../../../utils/tenant' +import { getRealClientIp } from '../../../utils/ip' /** * 证件 OCR 识别(身份证人像面 / 营业执照) @@ -15,11 +16,16 @@ export default defineEventHandler(async (event) => { const ctx = getTenantFromContext(event, config) const body = await readBody(event) + // 透传真实客户端 IP:后端按 IP 对匿名付费的 OCR 接口限流(注册页在登录前调用)。 + // 不透传时后端 IpUtil 只能拿到 Nuxt 服务器的出口 IP,限流会退化成「整个官网共用一份配额」, + // 正常用户反而被误限,而 H5 浏览器直连后端却能拿到真实 IP —— 同一策略两条链路行为相反。 + const clientIp = getRealClientIp(event) + try { const res = await $fetch('/hjc/ocr/recognize', { baseURL: config.public.modulesApiBase, method: 'POST', - headers: { TenantId: ctx.tenantId }, + headers: { TenantId: ctx.tenantId, 'X-Forwarded-For': clientIp }, query: { TenantId: ctx.tenantId }, body }) as any