From 1066625078037a95fa919eff89abb559c482ae0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com>
Date: Sun, 13 Sep 2026 21:21:48 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E5=93=81=E7=89=8C=E6=9C=8D=E5=8A=A1):=20?=
=?UTF-8?q?=E5=86=85=E9=83=A8=E6=8E=A5=E5=8F=A3=E6=8C=89=20uid=20=E4=BE=9B?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BB=A3=E7=90=86=E6=8F=90=E5=8F=96=E9=93=BE?=
=?UTF-8?q?=E6=8E=A5=EF=BC=9B=E4=BB=A3=E7=90=86=E6=A3=80=E6=B5=8B=E6=94=B9?=
=?UTF-8?q?=E7=9C=9F=E5=AE=9E=E6=8F=90=E5=8F=96+=E8=BD=AC=E5=8F=91?=
=?UTF-8?q?=E6=8E=A2=E6=B5=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 /api/internal/user-proxy(X-Internal-Token 自校验,18080 公网可达必须校验),
供主机 A 品牌检测服务(15126)按 uid 取用户代理提取链接,未配置返回空串
- 代理检测修复"假通过":旧实现把提取链接直接当静态代理交给 HttpClientPool,
链接无显式端口解析失败静默回退直连,检测到的是自家站点直连响应(40 个用户
3-39ms 全 301 假通过);现在先真实提取一次(余额不足/解析失败如实报),
再经提取到的代理请求自家域名,兼容旧静态代理地址
---
.../InternalUserProxyController.java | 61 +++++++++
.../service/UserApiSecretCheckService.java | 129 ++++++++++++++++--
.../InternalUserProxyControllerTest.java | 76 +++++++++++
.../UserApiSecretCheckServiceTest.java | 52 +++++++
4 files changed, 310 insertions(+), 8 deletions(-)
create mode 100644 backend-java/src/main/java/com/nanri/aiimage/modules/usersecret/controller/InternalUserProxyController.java
create mode 100644 backend-java/src/test/java/com/nanri/aiimage/modules/usersecret/controller/InternalUserProxyControllerTest.java
diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/usersecret/controller/InternalUserProxyController.java b/backend-java/src/main/java/com/nanri/aiimage/modules/usersecret/controller/InternalUserProxyController.java
new file mode 100644
index 00000000..b71110f3
--- /dev/null
+++ b/backend-java/src/main/java/com/nanri/aiimage/modules/usersecret/controller/InternalUserProxyController.java
@@ -0,0 +1,61 @@
+package com.nanri.aiimage.modules.usersecret.controller;
+
+import com.nanri.aiimage.common.api.ApiResponse;
+import com.nanri.aiimage.common.exception.BusinessException;
+import com.nanri.aiimage.modules.admin.support.AdminAuthSupport;
+import com.nanri.aiimage.modules.usersecret.service.UserApiSecretService;
+import com.nanri.aiimage.modules.usersecret.support.UserSecretModule;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 内部接口:按 uid 取用户代理提取链接,供主机 A 品牌检测服务(15126)读取。
+ *
+ *
鉴权:仅凭 X-Internal-Token(与容器 AIIMAGE_INTERNAL_TOKEN / 宿主机
+ * ~/.aiimage/internal-token 同值)。/api/internal 前缀不在 AdminApiGuardFilter
+ * 的兜底名单内,controller 必须自校验令牌——18080 公网可达,漏校验即匿名泄露
+ * 用户代理密钥。
+ *
+ *
日志不落明文;proxyUrl 为空串表示该用户未配置代理(调用方退化为直连)。
+ */
+@RestController
+@RequiredArgsConstructor
+@Slf4j
+@RequestMapping("/api/internal")
+@Tag(name = "内部接口", description = "服务间调用(X-Internal-Token 鉴权)。")
+public class InternalUserProxyController {
+
+ private final UserApiSecretService userApiSecretService;
+ private final AdminAuthSupport adminAuthSupport;
+
+ @GetMapping("/user-proxy")
+ @Operation(summary = "按 uid 取用户代理提取链接",
+ description = "明文返回该用户的代理提取链接(仅内部令牌可调);未配置返回空串。")
+ public ApiResponse