微服务网关白名单配置依然401解决方案
问题描述
在 RuoYi-Cloud-Plus 微服务项目中,/auth4a/logout 接口已经在网关白名单中配置,但在生产环境仍然返回 401 错误:
{
"code": 401,
"msg": "未能读取到有效 token",
"data": null
}
关键现象:
- 开发环境正常
- 生产环境 401
- 网关日志显示白名单已包含
/auth4a/logout
问题根因分析
1. 请求链路
微服务架构中的请求链路:
客户端请求
↓
[Nginx 反向代理]
↓
[网关层 - AuthFilter (Sa-Token)]
↓
后端服务
2. 网关白名单配置
网关配置 (ruoyi-gateway.yml):
security:
ignore:
whites:
- /auth4a/logout/**
网关过滤器 (AuthFilter.java):
SaRouter.match("/**")
.notMatch(ignoreWhite.getWhites()) // 白名单放行
.check(r -> {
StpUtil.checkLogin();
});
3. Nginx 代理路径问题(核心原因)
错误配置:
location /prod-api/ {
proxy_pass http://server; # ❌ 没有 / 结尾
}
请求转发流程:
客户端: /prod-api/auth4a/logout
↓ Nginx 转发(保留前缀)
网关: /prod-api/auth4a/logout # ❌ 不匹配白名单 /auth4a/logout
↓
401 错误
正确配置:
location /prod-api/ {
proxy_pass http://server/; # ✓ 带 / 结尾
}
正确的转发流程:
客户端: /prod-api/auth4a/logout
↓ Nginx 转发(去掉 /prod-api/)
网关: /auth4a/logout # ✓ 匹配白名单
↓ 匹配路由 /auth4a/**
↓ StripPrefix=1(去掉 /auth4a)
后端服务: /logout
解决方案
确保 Nginx 代理配置正确
修改文件: docker/nginx/conf/nginx.conf
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# websocket参数
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://server/; # ✓ 必须以 / 结尾
}
关键点:
location /prod-api/必须以/结尾proxy_pass http://server/必须以/结尾- 这样才能正确去掉
/prod-api/前缀
Nginx proxy_pass 路径规则详解
规则对比
| 配置 | 客户端请求 | 实际转发 | 说明 |
|---|---|---|---|
proxy_pass http://server; | /api/users | http://server/api/users | 保留完整路径 |
proxy_pass http://server/; | /api/users | http://server/users | 替换 location 部分 |
proxy_pass http://server/v1; | /api/users | http://server/v1users | 拼接路径(注意没有 /) |
proxy_pass http://server/v1/; | /api/users | http://server/v1/users | 替换并添加前缀 |
关键规则
- 带
/结尾:替换 location 匹配的部分 - 不带
/结尾:拼接完整路径 - location 必须以
/结尾:确保路径匹配正确
最佳实践
1. 白名单配置原则
网关层白名单:配置在 ruoyi-gateway.yml
# 推荐使用通配符
security:
ignore:
whites:
- /auth4a/logout/** # 匹配所有子路径和参数
- /auth4a/login/**
# 避免精确匹配
# whites:
# - /auth4a/logout # 可能不匹配 /auth4a/logout?xxx=xxx
2. Nginx 配置规范
# 统一使用 / 结尾
location /prod-api/ {
proxy_pass http://server/;
}
# 添加注释说明
location /prod-api/ { # 路径必须以 / 结尾
proxy_pass http://server/; # 必须以 / 结尾
}
