Vue history模式下Nginx拦截/login路由重写SSO不生效问题
问题成因
规则不生效的核心逻辑是Nginx的location匹配优先级、配置顺序和Vue History模式的兜底机制冲突:
- Nginx的location匹配遵循「精确匹配 > 前缀匹配 > 正则匹配」的优先级规则,绝大多数用户配置时会把Vue History模式需要的
try_files $uri $uri/ /index.html;兜底规则放在最靠前的位置,/login路径没有单独做高优先级的精确匹配,请求直接被try_files兜底返回了前端入口index.html,根本不会执行后续写的rewrite逻辑。 - 部分用户把/login的rewrite规则写在了
location /块的try_files规则之后,Nginx执行到try_files就已经完成请求转发,后续的rewrite规则不会被触发。 - 如果前端vue-router路由表中提前定义了/login路径的对应路由,即便请求到达前端,也会直接被前端路由接管渲染对应页面/404页,不会触发跳转。
正确配置方案
配置核心原则:/login的跳转规则必须用精确匹配独立定义,放在所有通用路由规则的最前面,优先级高于前端History模式的兜底规则。
单域名固定跳转配置
适用于单个业务域名跳固定SSO地址的场景,参考配置如下:
server { listen 80; # 按需配置https监听443端口、ssl证书相关规则 server_name 你的业务访问域名; # 替换为Vue项目打包后dist文件夹的服务器绝对路径 root /data/web/your-vue-project/dist; index index.html; # 精确匹配/login路径,优先级最高,直接返回302跳转,不会走到后续兜底规则 location = /login { return 302 你配置的对应SSO登录地址; } # Vue History模式通用兜底规则 location / { try_files $uri $uri/ /index.html; } }
多域名动态匹配跳转配置
适用于同一套服务绑定多个域名,需要按访问域名跳对应SSO地址的场景,参考配置如下:
server { listen 80; # 按需配置https监听443端口、ssl证书相关规则 # 绑定所有需要支持的业务域名 server_name 业务域名A 业务域名B 业务域名C; root /data/web/your-vue-project/dist; index index.html; location = /login { # 按访问host做映射,匹配对应SSO地址 set $sso_target ""; if ($host = "业务域名A") { set $sso_target "A域名对应的SSO登录地址"; } if ($host = "业务域名B") { set $sso_target "B域名对应的SSO登录地址"; } if ($host = "业务域名C") { set $sso_target "C域名对应的SSO登录地址"; } # 兜底默认SSO地址可按需配置 if ($sso_target = "") { set $sso_target "默认SSO登录地址"; } return 302 $sso_target; } location / { try_files $uri $uri/ /index.html; } }
配置校验注意事项
- 配置修改完成后,先执行
nginx -t校验配置语法是否正确,确认无报错后执行nginx -s reload重载配置,规则才会生效。 - 删除前端vue-router路由表中定义的/login相关路由规则,避免前端路由提前接管请求。
- 测试规则时优先用
curl -I http://你的业务域名/login查看响应头的Location字段是否为预期的SSO地址,排除浏览器缓存、Service Worker缓存的干扰,确认规则生效后再用浏览器验证。 - 禁止将/login的跳转规则写在
location /块内的try_files规则之后,会被try_files截断逻辑导致规则不生效。
内容的提问来源于stack exchange,提问作者tomsma
相关产品推荐
相关产品推荐

