Nginx防止cookie丢失的配置 <nginx proxy_pass> <proxy_cookie_domain>
一、proxy_cookie_path 参数的作用是用来改变cookie的路径
语法: proxy_cookie_path path replacement;
path就是你要替换的路径 replacement 就是要替换的值
为什么cookie 会丢失?
比如说一个没有经过代理的地址 : http://127.0.0.1/project cookie_path:/project
如果按照第二种方式代理那么地址就是 : http://127.0.0.1/proxy_path cookie_path: /proxy_path
如果cookie_path与地址栏上的path不相符游览器就不会接受这个cookie,自然session就失效了。
解决nginx proxy_pass反向代理cookie,session丢失的问题
下面是可能的三种情况
1)host、端口转换,cookie不会丢失
location /project { proxy_pass http://127.0.0.1:8080/project; }
通过浏览器访问http://127.0.0.1/project时,浏览器的cookie内有jsessionid。再次访问时,浏览器会发送当前的cookie。
2)如果路径也变化了,则需要设置cookie的路径转换,nginx.conf的配置如下
location /proxy_path { proxy_pass http://127.0.0.1:8080/project; }
通过浏览器访问http://127.0.0.1/proxy_path时,浏览器的cookie内没有jsessionid。再次访问时,后台当然无法获取到cookie了。
加上路径转换:proxy_cookie_path /project /proxy_path;则可以将project的cookie输出到proxy_path上。
保证cookie不丢失的正确配置是:
location /proxy_path { proxy_pass http://127.0.0.1:8080/project; proxy_cookie_path /project /proxy_path; }
3)直接代理本地端口
location /proxy_path { proxy_pass http://127.0.0.1:8080/; proxy_cookie_path /project /proxy_path; # project 为你的项目名 也可用变量代替 }
二、proxy_cookie_domain 参数的作用是转换response的set-cookie header中的domain选项,由后端设置的域名domain转换成你的域名replacement,来保证cookie的顺利传递并写入到当前页面中,注意proxy_cookie_domain负责的只是处理response set-cookie头中的domain属性,仅此而已!
在了解了这个参数后,发现不配置这个属性,依然运转正常!
response在写set-cookie的时候,domain是一个可选项,并不是必填项,所以经常能看到如下这种情况:
这个时候由于set-cookie本身就没有domain内容,proxy_cookie_domain也就不没有必要了,这也是为什么在部分项目中不配置proxy_cookie_domain依然正常的原因。但是对于一些设置了domain的项目,比如:
这种情况下当你用nginx做反向代理的时候,就必须要转换一下了。
===================== Nginx反向代理理解误区之proxy_cookie_domain ======================
之前错误地理解:proxy_cookie_domain的作用是实现前后端cookie域名转换,保证顺利传递!比如说Nginx做反向代理的时候,一般都习惯添加proxy_cookie_domain配置,来做cookie的域名转换。比如:
... location /api { proxy_pass https://b.test.com; proxy_cookie_domain b.test.com a.test.com; } ...
后面发现,不配置这个属性,依然运转正常!这就是对proxy_cookie_domain错误理解导致地!!乍一看好像也没错,但是现在想想,理解还是不够啊,因为proxy_cookie_domain的作用是单向的,并不是双向转换的。我们先看下cookie的传递过程:
浏览器在发送请求的时候,会在request header中带上cookie项(有内容的话),此时的cookie是一个字符串,一个key=value并用分号分割的字符串,
其中并不包含任何域名信息。这是因为浏览器在设置cookie选项的时候,所选取的内容都是缓存中接口域名下的。然后request的只要请求发送出去之后,cookie中有关domain信息其实是不存在的,它只是一个普通的字符串,随便proxy_pass到任何位置,都会正常携带下去。因此在前端到后端的request的过程中,proxy_cookie_domain是没用的!!
而server端在做响应的时候,通过set-cookie的domain属性,可以控制cookie的生效域名目标,做到诸如二级域名cookie分离等等,如果前端接收到的set-cookie的domain和当前域名不一致,或者一级域名不一致(二级域名可以共享一级域名下的cookie),这个cookie在后续的通信中就是无效的,所以这里才需要去做domain的转换,也就是说response中set-cookie的domain转换才是有意义的,这也正是proxy_cookie_domain的作用所在。
当response的set-cookie中domain不去设置时,cookie顺利传入浏览器中,浏览器会自动设置这个cookie的生效域名为当前域名。
和这个类似的还有proxy_cookie_path属性,同样的该属性仅作用在修改response set-cookie的path属性,而一般情况下,用的也比较少。
下面是Nginx里关于proxy_cookie_domain的一个配置:
页面地址是a.com,但是要用b.com的cookie需要 proxy_set_header Cookie $http_cookie; location / { proxy_cookie_domain b.com a.com; #注意别写错位置了 proxy_cookie_path / /; proxy_pass http://b.com; }