关于浏览器存不住cookie的问题

场景:前端域名配置了ssl证书,Nginx使用反向代理进行转发,配置如下

js
复制代码
#反向代理-START location ^~ /backend/ { proxy_pass http://127.0.0.1:8668/; # 指向后端端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #反向代理-END

pc端访问域名:https://xxx.xxxxxx.xxxx 进行登录 前端发送了两个请求,分别为

第一个登录请求返回了用户信息,但第二个请求却是无权限,直接回到了登录页面

排查:经过排查发现,登录接口返回的响应头返回了Cookie

text
复制代码
set-cookie: JSESSIONID=A054FD308D135F5948AA22C8A9CA1218; Max-Age=2592000; Expires=Sun, 14 Dec 2025 06:29:53 GMT; Path=/backend/api; HttpOnly

但在获取用户信息的请求中还是无权限,且又返回了一遍Cookie

分析:后端服务在 /api/user/login 接口成功登录后,返回了一个 Set-Cookie 响应头。 在获取用户信息时前端的实际请求为https://xxx.xxxxxx.xxxx/backend/api/user/get/login 当这个请求到达 Nginx 时,location ^~ /backend/ 规则会生效,将请求转发到 http://127.0.0.1:8668/

  • Nginx 收到的路径/backend/api/user/get/login
  • 转发到后端的路径/api/user/get/login

浏览器要发送 https://xxx.xxxxxx.xxxx/backend/api/user/get/login 请求时,会检查自己的 Cookie 仓库。 它发现有一个cookie,其 Path 是 /api 浏览器会将当前请求的路径 (/backend/api/user/get/login) 与 Cookie 的 Path (/api) 进行比较 浏览器只会在请求路径以 /api 值开头 时才发送该 Cookie 但/backend/api/user/get/login不是以/api/开头的,所以浏览器决定不发送cookie 这才导致了无权限的问题

解决:修改 Nginx 配置 不改变后端的任何代码,通过调整 Nginx 配置,让浏览器认为 /backend 目录下的所有请求都应该带上 Path=/api 的 Cookie 在反向代理的配置中,增加一个proxy_cookie_path指令,其作用为:

  • 如果发现响应头中有 Set-Cookie,并且其 Path 属性值为 /api,Nginx 就会将其修改为 /backend/api,再发送给浏览器。
  • 浏览器收到的 Set-Cookie 就变成了:JSESSIONID=...; Path=/backend/api; ...
  • 当下次浏览器请求 /backend/api/user/get/login 时,路径是以 /backend/api 开头的,所以它会正确地带上 Cookie

反向代理配置修改后如下:

text
复制代码
#反向代理-START location ^~ /backend/ { proxy_pass http://127.0.0.1:8668/; proxy_cookie_path /api /backend/api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #反向代理-END

此时再次测试登录,问题完美解决

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
玄德
下载 APP