cookie跨域传输cookie问题:nginx跨域代理之proxy_cookie_domain
Author:zhoulujun Date:
cookie作为辨别用户身份、进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),存储格式如下:
Set-Cookie: NAME=VALUE(key1=value1&key2=value2);Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
Expires 限定本地数据缓存事件
Domain确定哪些域名可以访问该数据,默认为存储数据时相对应的域名。
Path限定哪些路径可以访问该数据,如果值为“/”,则Web服务器上所有的WWW资源均可读取该Cookie,默认为存储是对应路径
Secure 限定通信只有是加密协议时,才可读取本地数据。目前只有https。
跨域传输cookie解决方案
设置cookie Domain
通过设置cookie Domain 只能解决主域名相同的 跨子域名的跨域问题。例如将cookie的domain设置为.zlj.cn;name a.zlj.com b.zlj.cn等都能访问此cookie。
但是此法无法解决跨主域名的的问题。
设置http头解决跨域问题
CORS为我们提供了跨域资源共享的解决方案,通过Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers Access-Control-Allow-Methods Access-Control-Expose-Headers Access-Control-Max-Age Access-Control-Request-Headers Access-Control-Request-Method Origin
Access-Control-Allow-Credentials 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。
Credentials可以是 cookies, authorization headers 或 TLS client certificates。
前端跨域传输cookie到服务端,需要三个条件:
Access-Control-Allow-Origin不能为*,应为具体域名
服务端Access-Control-Allow-Credentials应为true
客户端XMLHttpRequest 的 withCredentials=true
在服务端,需要
response.addHeader("Access-Control-Allow-Origin", "demo.zhoulujun.cn");
response.addHeader("Access-Control-Allow-Credentials", "true");
前端ajax操作
$.ajax({ url : 'xxx', xhrFields: { withCredentials: true // 设置运行跨域操作 }}); //jquery axios(url, { method: 'GET', mode: 'no-cors', headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json', }, withCredentials: true, credentials: 'same-origin', }).then(response => { })
这个比较麻烦,还是nginx代理比较方便
chrome80 后跨域解决方案
chrome80版本的声明
大致就是说80以后的版本,cookie默认不可跨域,除非服务器在响应头里再设置same-site属性。因为默认属性不再是lax
same-site属性设置
same-site有3种值可以设置:strict,lax,none
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
None,Cookie 只能通过 HTTPS 协议发送。必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
Set-Cookie: widget_session=abc123; SameSite=None; Secure
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
请求类型 示例 正常情况 Lax 链接 <a href="..."></a>
发送 Cookie 发送 Cookie 预加载 <link rel="prerender" href="..."/>
发送 Cookie 发送 Cookie GET 表单 <form method="GET" action="...">
发送 Cookie 发送 Cookie POST 表单 <form method="POST" action="...">
发送 Cookie 不发送 iframe <iframe src="..."></iframe>
发送 Cookie 不发送 AJAX $.get("...")
发送 Cookie 不发送 Image <img src="...">
发送 Cookie 不发送
nginx使用proxy_pass反向代理时
如果只是host、端口转换,则cookie不会丢失。浏览器的cookie内有jsessionid。再次访问时,浏览器会发送当前的cookie。
如果路径也变化了,则需要设置cookie的路径转换,详细看了文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html?&_ga=1.161910972.1696054694.1422417685#proxy_cookie_path
location /proxy_path { proxy_pass http://zhoulujun.cn/project; proxy_cookie_path /project /proxy_path; # proxy_cookie_domain b.zlj.com a.zlj.com;#如果cookie没有设置domain,无需配置(一般情况没有配置) }
经过后端中转,基本可以解决所有问题,但是也带来多余的消耗
proxy_cookie_domain参数的作用是转换response的set-cookie header中的domain选项,由后端设置的域名domain转换成你的域名replacement,来保证cookie的顺利传递并写入到当前页面中,注意proxy_cookie_domain负责的只是处理response set-cookie头中的domain属性,仅此而已。
参考文章:
Cookie 的 SameSite 属性 www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
转载本站文章《cookie跨域传输cookie问题:nginx跨域代理之proxy_cookie_domain》,
请注明出处:https://www.zhoulujun.cn/html/tools/webServer/nginx/2020_0526_8439.html