【Easylive】AdminFilter 详细解析
【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版
AdminFilter 详细解析
AdminFilter
是一个 Spring Cloud Gateway 的过滤器,用于在请求到达微服务之前进行 权限校验(如管理员 Token 验证)。以下是逐行解析:
1. 类定义与基础结构
@Component
@Slf4j
public class AdminFilter extends AbstractGatewayFilterFactory {
• @Component
:声明为 Spring Bean,由 Spring 管理生命周期。
• @Slf4j
:集成 Lombok,提供日志功能(如 log.error()
)。
• AbstractGatewayFilterFactory
:Spring Cloud Gateway 过滤器的基类,用于自定义路由过滤逻辑。
2. 常量定义
private final static String URL_ACCOUNT = "/account";
private final static String URL_FILE = "/file";
• URL_ACCOUNT
:放行路径,访问 /account
的请求无需 Token(如登录、注册接口)。
• URL_FILE
:特殊路径,文件相关接口从 Cookie 中提取 Token(而非 Header)。
3. 核心过滤逻辑 (apply
)
@Override
public GatewayFilter apply(Object config) {return (exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();
• apply
:覆盖父类方法,返回一个 GatewayFilter
实例。
• exchange
:封装了 HTTP 请求和响应的上下文(类似 Servlet 的 HttpServletRequest
/Response
)。
• chain
:过滤器链,调用 chain.filter(exchange)
继续执行后续过滤器或路由到目标服务。
4. 路径判断与 Token 提取
(1) 放行 /account
路径
if (request.getURI().getRawPath().contains(URL_ACCOUNT)) {return chain.filter(exchange); // 直接放行
}
• 逻辑:如果请求路径包含 /account
(如登录接口),跳过 Token 校验。
(2) 文件接口从 Cookie 取 Token
if (request.getURI().getRawPath().contains(URL_FILE)) {token = getTokenFromCookie(request); // 从 Cookie 获取
}
• 适用场景:文件上传/下载可能通过浏览器发起,而浏览器通常将 Token 放在 Cookie 而非 Header。
(3) 默认从 Header 取 Token
String token = getToken(request); // 从 Header 获取
• Header 键名:Constants.TOKEN_ADMIN
(如 X-Admin-Token
)。
5. Token 校验
if (StringTools.isEmpty(token)) {throw new BusinessException(ResponseCodeEnum.CODE_901); // 抛出"无权限"异常
}
• 校验规则:
• 如果 Token 为空,抛出业务异常(CODE_901
可能表示 “未登录” 或 “Token 无效”)。
• 如果 Token 有效,继续执行后续逻辑(chain.filter(exchange)
)。
6. Token 提取方法
(1) 从 Header 获取
private String getToken(ServerHttpRequest request) {return request.getHeaders().getFirst(Constants.TOKEN_ADMIN);
}
• 示例:
请求 Header 需包含:
GET /api/admin/users HTTP/1.1
X-Admin-Token: abc123xyz
(2) 从 Cookie 获取
private String getTokenFromCookie(ServerHttpRequest request) {return request.getCookies().getFirst(Constants.TOKEN_ADMIN).getValue();
}
• 示例:
浏览器请求会自动携带 Cookie:
GET /file/download/1 HTTP/1.1
Cookie: ADMIN_TOKEN=abc123xyz
7. 设计思想总结
关键点 | 说明 |
---|---|
职责分离 | 将权限校验逻辑集中到网关层,避免每个微服务重复实现。 |
灵活提取 Token | 支持 Header 和 Cookie 两种方式,适配不同场景(如 API 调用 vs 浏览器文件下载)。 |
白名单路径 | /account 路径免校验,确保登录/注册接口可访问。 |
异常处理 | 直接抛出业务异常,由网关统一转换为 HTTP 响应(如 401 Unauthorized)。 |
8. 使用场景示例
(1) 管理员访问用户列表
GET /admin/users HTTP/1.1
X-Admin-Token: valid_token_here
• 流程:
- 网关检查路径不匹配
/account
或/file
。 - 从 Header 提取
X-Admin-Token
。 - 校验通过,转发请求到用户微服务。
(2) 用户下载文件
GET /file/download/1 HTTP/1.1
Cookie: ADMIN_TOKEN=valid_token_here
• 流程:
- 网关识别路径包含
/file
。 - 从 Cookie 提取
ADMIN_TOKEN
。 - 校验通过,转发请求到文件微服务。
(3) 未携带 Token 的请求
GET /admin/users HTTP/1.1
• 结果:抛出 CODE_901
异常,返回 401 Unauthorized
。
总结
AdminFilter
是网关层的 统一权限守卫,通过 路径判断 和 多方式 Token 提取,确保只有合法请求能访问后端服务。它的设计体现了网关的核心价值:集中式管控跨横切面逻辑。