nginx使用proxy_pass反向代理时,cookie丢失的问题

场景:

  • 公司的某个项目是tomcat的Java项目,在本地部署已经没有问题,部署到线上通过内网IP+端口访问没有问题。

  • 接下来要做的就是映射成官网的一个二级域名,映射后测试发现怎么都登不上去,登录页面反复刷新就是不进去。

  • F12发现已经过了用户校验接口,然后发现浏览器Cookie为空,测试本地项目Cookie不为空,于是知道是Cookie没有存上,每次登陆都是正确登录了的,但是服务端要求存的cookie浏览器没有保存,每次请求没有带上cookie,服务端就一直认为你没有登录,反复刷登录页面;

问题已经找到了,如何解决呢?

架构:Nginx在前面做二级域名转发,tomcat本身没有问题,那问题就是在Nginx上面;

做测试:

  1. 模拟域名:
    hosts文件添加

     127.0.0.1 local.com
     127.0.0.1 sub.local.com
    
  2. 配置Nginx—nginx.conf

     http {
         include       mime.types;
         default_type  application/octet-stream;
         sendfile        on;
         keepalive_timeout  65;
    
         server {
             listen       80;
             server_name  localhost;
    
             location / {
                 root   html;
                 index  index.html index.htm;
             }
    
             error_page   500 502 503 504  /50x.html;
             location = /50x.html {
                 root   html;
             }
         }
    
         server {
         server_name sub.local.com;
         listen 80;
         location / {
             proxy_pass http://127.0.0.1:8080/crm/;
             proxy_redirect default;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection $http_connection;
         }
       }
    
  3. 部署tomcat完成,访问 127.0.0.1:8080 正常,项目登录正常,Cookie正常

  4. 启动nginx,访问 local.com 出现Nginx默认页面,正常

  5. 访问 sub.local.com 显示登录页面,登录失败,Cookie存储失败—问题就在Nginx转发上面。

  6. 查找资料: http://blog.csdn.net/we_shell/article/details/45153885
    这里添加了proxy_cookie_path /project /;
    前面是项目地址,后面是访问地址

  7. 重启Nginx ,访问 sub.local.com 正常了;

另一种方法:

  1. 在tomcat server.xml中
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path ="/" docBase ="crm" debug ="0" privileged ="true"></Context>

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

      </Host>

添加这一行之后,访问 127.0.0.1:8080 就可以,无需加上后面的项目名称

  1. 修改Nginx.conf
    proxy_pass http://127.0.0.1:8080/;
    也不要加上后面的项目名称,重启就可以正常访问,这里就相当于只是做了端口转发。

附:

  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了。
详细看了文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html?&_ga=1.161910972.1696054694.1422417685#proxy_cookie_path

加上路径转换:proxy_cookie_path /project /proxy_path;
则可以将project的cookie输出到proxy_path上。正确的配置是:

location /proxy_path { 
    proxy_pass http://127.0.0.1:8080/project;
    proxy_cookie_path /project /proxy_path;
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×