记一次nginx反向代理引发的没法登陆问题

背景

事情是这样的,公司之前开发了一套系统,可是由于国家政策缘由下线了,时隔两年,如今能够从新上线了,可是只有代码,相关环境的配置是没有的。在从新上线的过程当中,遇到了系统没法登录的问题。这套系统架构是这样的:nginx做为web接入层,数据处理会反向代理到tomcat上跑的java服务。一开始我怀疑是否是代码逻辑有问题,可是开发称代码是没问题的,为此,开发还将获取数据请求跳过nginx直接抛给Tomcat,结果就真的没问题了。可是实际生产中是不能这样跑的,由于这样会暴露处理数据的Tomcat。因此只能在nginx这里找问题。html

排查过程

现象是这样的,登陆的时候会成功进入系统,可是会马上跳回登陆页面。登陆的过程会有一条post请求将登陆信息上传给系统,还有一条get请求获取登陆状态,可是我不清楚获取登陆状态的逻辑是怎样的,判断条件是什么,本想让开发看一下 代码逻辑的,可是开发也看不出个因此然来。接着我看了post和get请求的包头信息,包头信息以下:
post请求包头信息
image.png
get请求头区别
image.png
然而仅仅看这两个包头信息我看不出什么异常,因此我让开发将代码改成直接跳过nginx能够登陆的状况,我想对比能登陆和不能登陆的状况下有什么区别,如下是能登陆的状况下的包头信息:
post请求包头信息
image.png
get请求头区别
image.png
对比了两种状况的包头信息,我发现了一个区别(ps:请忽略Access-Control相关头信息差别,这是后面解决跨域加的),那就是不能登陆的时候post和get请求都有set-cookie,而能够登陆的时候,只有post请求有set-cookie。因此我猜测是post请求的时候登陆成功会生成一个cookie,而后get请求去读取cookie,获取到cookie即为登陆状态。因此我又对比了两种状况的cookie。不过在看cookie的具体状况以前,我要先说清楚两种状况下请求的区别。不能登陆的状况下,使用了nginx作反向代理,http://域名/字符串/XXX 会被反向代理到 http://域名:端口/项目名/XXX 即用项目名替代固定的字符串(听说这样作是为了区分测试环境和生产环境的),而后能够登陆的状况是不通过nginx代理,直接请求了http://域名:端口/项目名/XXX 。由于cookie里面涉及到这些,因此要先说清楚。下面是cookie的具体信息
不能登陆状况下post请求的cookie信息
1.jpg
不能登陆状况下get请求的cookie信息
2.jpg
能够登陆状况下post请求的cookie信息
image.png
能够登陆状况下get请求的cookie信息
4.jpg
能够看到的出来,能够登陆的状况下,确实是get请求去请求了post请求响应的cookie。那么为何通过nginx以后,get请求就没有这样去获取post响应的cookie呢?我查找‘nginx cookie’关键词,看到《解决nginx proxy_pass反向代理cookie,session丢失的问题》,了解到cookie_path要匹配请求的url才能获取到cookie,因而不能登陆问题就能获得合理的解释:当post请求http://域名/字符串/XXX 时,通过nginx反向代理到http://域名:端口/项目名/XXX ,此时cookie_path是在项目名下(从post请求包头能够看到),而后get请求http://域名/字符串/YYY ,可是这条请求里面没有项目名,获取不到上面post请求响应的放在项目名目录下面的cookie,因此被判断为没有登陆的状态,返回了登陆页,同时get请求也生成了一个cookie放在了项目名目录下。java

问题解决

第一种方案:修改cookie_path,nginx里面提供了proxy_cookie_path指令修改cookie_path,用法:proxy_cookie_path 原地址 修改地址 官网传送门
通过测试,修改地址只要知足请求url域名后的目录最左匹配规则都是能够的,好比个人请求是http://域名/a/b/c/d/xxx ,反向代理到http://域名:端口/E/b/c/d/xxx ,那么cookie_path修改地址能够设置为/,/a,/a/b,/a/b/c,/a/b/c/d,示例:nginx

location /a/ {
    proxy_pass   http://127.0.0.1:8080/E/;
    proxy_cookie_path  /E /a;
}

第二种方案:修改请求地址,让请求地址和反向代理地址相匹配,如请求地址http://域名/字符串/XXX 被反向代理到 http://域名:端口/项目名/XXX ,那么能够修改请求地址为http://域名/项目名/XXX ,这样就不须要配置proxy_cookie_path。web

参考:
解决nginx proxy_pass反向代理cookie,session丢失的问题跨域

相关文章
相关标签/搜索