feat(gateway): 修改文件上传接口返回结构并添加认证路径白名单
- 将 POST /system/file/upload 接口返回结构从字符串改为 { id: string, url: string } 对象
- 添加 id 字段作为 infra_file.id 的字符串形式,解决前端精度丢失问题
- 新增 SKIP_AUTH_PATHS 白名单集合,包含登录、登出、刷新令牌等免校验路径
- 在网关过滤器中添加白名单检查逻辑,跳过指定路径的 access token 校验
- 解决过期 token 拦截导致刷新令牌接口无法正常执行的问题
This commit is contained in:
@@ -25,6 +25,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.njcn.rdms.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
|
||||
@@ -37,6 +38,18 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private static final LoginUser LOGIN_USER_EMPTY = new LoginUser();
|
||||
|
||||
/**
|
||||
* 跳过 access token 校验的路径白名单。
|
||||
* 这些接口在 system 端标注 @PermitAll,本就不需要登录态;若前端调用时带过期 access,
|
||||
* 网关不应在此处拦截 1002023000,否则 /refresh-token 永远走不到 system 的 1002023001 / 业务逻辑。
|
||||
*/
|
||||
private static final Set<String> SKIP_AUTH_PATHS = Set.of(
|
||||
"/admin-api/system/auth/login",
|
||||
"/admin-api/system/auth/logout",
|
||||
"/admin-api/system/auth/refresh-token",
|
||||
"/admin-api/system/auth/register"
|
||||
);
|
||||
|
||||
private final WebClient webClient;
|
||||
|
||||
private final LoadingCache<String, LoginUser> loginUserCache = buildAsyncReloadingCache(Duration.ofMinutes(1),
|
||||
@@ -58,6 +71,11 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
exchange = SecurityFrameworkUtils.removeLoginUser(exchange);
|
||||
|
||||
// 白名单路径直接放行,不做 token 校验
|
||||
if (SKIP_AUTH_PATHS.contains(exchange.getRequest().getPath().value())) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
String token = SecurityFrameworkUtils.obtainAuthorization(exchange);
|
||||
if (StrUtil.isEmpty(token)) {
|
||||
return chain.filter(exchange);
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# 文件上传接口改造需求(给后端)
|
||||
|
||||
> 提单时间:2026-05-11
|
||||
> 提单方:前端
|
||||
> 涉及模块:`rdms-system-boot` 文件模块
|
||||
> 背景:业务表单(如新建/编辑任务)的附件采用「即传即存」交互,但表单可能被用户取消或关闭。前端需要在合适时机调用删除接口清理孤儿文件。当前 `/system/file/upload` 只返回 url,前端拿不到 fileId,无法触发删除。
|
||||
|
||||
---
|
||||
|
||||
## 1. 改造:`POST /system/file/upload`
|
||||
|
||||
**路径 / 方法 / 入参全部保持不变**,仅修改返回结构。
|
||||
|
||||
### 1.1 现状返回
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"data": "http://192.168.1.107:9009/rdms/20260508/xxx.jpg?X-Amz-..."
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 目标返回
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"data": {
|
||||
"id": "10001",
|
||||
"url": "http://192.168.1.107:9009/rdms/20260508/xxx.jpg?X-Amz-..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 字段说明
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| id | string | 是 | 即 `infra_file.id`,**必须以字符串形式返回**,不要返回 number |
|
||||
| url | string | 是 | 文件访问 URL,含义与现状完全一致(私有桶带签名,公开桶裸 URL) |
|
||||
|
||||
### 1.4 关键约束
|
||||
|
||||
- **`id` 必须是 string,不是 number**。原因:`infra_file.id` 是 Long 类型,超过 JS 安全整数(2^53)时 JSON number 会精度丢失。前端项目 ID 统一按字符串接收。
|
||||
- 该改动**不兼容老返回结构**,前端会同步切换。
|
||||
- App 端 `/app-api/system/file/upload` 前端目前未使用,可暂不改;若希望对称建议一起改。
|
||||
|
||||
---
|
||||
|
||||
## 2. 确认:`DELETE /system/file/delete`
|
||||
|
||||
接口已存在(见 `system-file-api.md` §4.3.5),无需新建,但需确认以下两点:
|
||||
|
||||
### 2.1 权限
|
||||
|
||||
- 业务用户角色需具备 `system:file:delete` 权限码,**或**该接口允许"删除自己上传的文件"无需该权限码。
|
||||
- 期望:当前业务用户能直接调通 `DELETE /admin-api/system/file/delete?id=xxx`。
|
||||
|
||||
### 2.2 幂等性(删不存在的文件)
|
||||
|
||||
- 当前文档里删不存在的文件返回错误码 `1001003001 / 文件不存在`。
|
||||
- 期望:**幂等返回 `code: 0`**(更佳),或维持现状(前端会把该错误码当作"已删除"吞掉,也能接受)。
|
||||
|
||||
### 2.3 入参
|
||||
|
||||
保持现状不变:
|
||||
|
||||
```
|
||||
DELETE /admin-api/system/file/delete?id=10001
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 不在本次范围(避免误解)
|
||||
|
||||
以下事项**本次不做**,属于后续「治本方案」范畴,请勿顺手改动:
|
||||
|
||||
- 不需要在 `infra_file` 表加 `status`(temp / committed)字段
|
||||
- 不需要加业务引用关系表
|
||||
- 不需要做孤儿文件定时清理 cron
|
||||
- 不需要改 `/presigned-url` 与 `/create`
|
||||
- 不需要改 App 端 `/upload` 鉴权策略
|
||||
|
||||
---
|
||||
|
||||
## 4. 联调要点
|
||||
|
||||
1. 改造完成后请提供测试环境,前端会同步发版。
|
||||
2. 接口返回的 `id` 请确保转为字符串再 JSON 序列化(不要直接序列化 Long)。
|
||||
3. 若返回里 `id` 是 number 类型,前端视为联调未通过。
|
||||
|
||||
---
|
||||
|
||||
## 5. 一句话总结
|
||||
|
||||
> `/system/file/upload` 返回结构从 `string` 改成 `{ id: string, url: string }`,`id` 是 `infra_file.id` 的字符串形式。其它接口不动。
|
||||
Reference in New Issue
Block a user