一同事求援:后台系统的登录成功了,但不能成功登进系统,仍然跳转到登录页,但同一套代码另一个环境却没有问题。

背景

经了解,他对同一个项目使用tomcat部署了两个环境,一个在开发服务器上,一个在他本机,两个环境代码配置完全相同。两边通过同一个nginx进行反向代理,nginx配置大致如下,

location /health/ {
proxy_pass http://192.168.40.159:8081/health/; #无问题的配置
} location /health-dev/ {
proxy_pass http://192.168.40.202:8080/health/; #有问题的配置
}

一个反向代理到开发环境,一个反向代理到本机服务。

定位

既然代码配置完全相同,那么问题很大可能就出现在nginx的反向代理上。

因为两边location路径不同(即浏览器路径不同),但是反向代理的服务端路径却相同,结合session的基本原理,如下图,

  1. 当浏览器第一次打开页面时,服务端会为这次会话创建一个session,并将session id通过response的header传递给浏览器,header一般为 Set-Cookie: JSESSIONID=xxxxx; Path=xxxx
  2. 浏览器接收到响应后,如果header Set-Cookie 中path的值与浏览器地址路径匹配,则将该header值存于浏览器的Cookie中
  3. 浏览器在下次请求服务器时,将Cookie中的JSESSIONID值通过request的header上报给服务端,header一般为 Cookie: JSESSIONID=xxxx;
  4. 服务端可通过该JSESSIONID来定位到对应的session

nginx反向代理按这种方式配置时

location /health-dev/ {
proxy_pass http://192.168.40.202:8080/health/;
}

浏览器访问 http://www.domian.com/health-dev 时,服务端返回的 Set-Cookie 的 Path 值为 /health(因为中间有反向代理,服务端并不知道代理前的路径是啥,是按最终请求服务端的路径设置),如图

因为浏览器访问地址的路径 /health-devSet-Cookie 的 Path /health 不匹配,所以浏览器并不会将其值存入Cookie中,如图

因此在下次请求服务器时,浏览器无法设置request Cookie header的 JSESSIONID 值,服务器无法定位到对应的session,因此会将其当做第一次请求,创建一个新的session,如此反复,因此就算你登录认证通过了,但服务器返回的登录凭证(JSESSIONID)浏览器不会保存,并在下次请求时携带,导致服务器认为你是一个新的请求,当然就会又跳到登录页面了。

解决

nginx有一个命令 proxy_cookie_path(参考: proxy_cookie_path)可将服务器返回的 Set-Cookie 中的path进行修改,格式为 proxy_cookie_path 原路径 目标路径,我们在配置中添加 proxy_cookie_path 如下。

location /health-dev/ {
proxy_pass http://192.168.40.202:8080/health/;
proxy_cookie_path /health /health-dev;
}

重启nginx,问题解决。


[转载请注明出处]

作者:雨歌

欢迎关注作者公众号:半路雨歌,查看更多技术干货文章

nginx反向代理导致session失效的问题处理的更多相关文章

  1. nginx反向代理导致请求header头信息丢失

    背景:前端与后端调试接口,后端拿不到前段发过去的请求头信息,导致接口不通.(但是在本地是可以拿到的) 原因:nginx做了反向代理,没有请求时候加头信息的配置 报错如下: 解决方法: 方法一:NGIN ...

  2. nginx 反向代理导致的session丢失的问题

    [原文链接] https://blog.csdn.net/xiaweiyidengzhewo/article/details/80921750 注意这篇文章解释的是“丢失”而不是“一致性”

  3. Nginx反向代理导致PHP获取不到正确的HTTP_HOST,SERVER_NAME,客户端IP的解决方法

    今天第一次陪Nginx负载均衡,发现PHP无法获取HTTP_HOST 贴上的Nginx配置 upstream abc.com { server 10.141.8.55:8005; server 10. ...

  4. 由Nginx反向代理引出的JCaptcha验证码验证失败的问题

    搜索关键字: 1)Windows本地开发正常,部署到Linux远程服务器上JCaptcha验证失败 2)Linux远程服务器上JCpatcha验证失败 3)Nginx反向代理后JCaptcha验证失败 ...

  5. nginx反向代理(proxy_pass)tomcat的过程中,session失效的问题解决

    Nginx反向代理tomcat,很是方便,但是也有些细节的问题需要注意:今天遇到了这样一个问题,tomcat中路径“host/web1”,nginx中直接“host/”代理,这时候session就无法 ...

  6. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  7. nginx配置反向代理支持session

    Nginx反向代理tomcat,很是方便,但是也有些细节的问题需要注意:今天遇到了这样一个问题,tomcat中路径“host/web1”,nginx中直接“host/”代理,这时候session就无法 ...

  8. Linux系统——Nginx反向代理与负载均衡

    集群集群是指一组(若干个)相互独立的计算机,利用高速通信网路组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运用各自服务的独立服务器.这些服务器之间可以彼此通信,协同向用户提供 ...

  9. nginx 反向代理与负载均衡应用实践

    集群介绍 集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服务器.这些服务器之间可以彼此通信,协同向 ...

随机推荐

  1. VMWare虚拟机开启时显示模块“Disk”启动失败的解决方案

    找到虚拟机所在的目录, 将 .vmx文件打开 将文件vmci0.present = "TRUE"改为 vmci0.present = "FALSE" 删除以.l ...

  2. git&github&Jenkins完成可持续集成

    1.安装git :想要安装Git首先要下载Git的安装包程序. Git安装包下载地址:https://git-scm.com/downloads/ 2.双击下载git安装包进入安装界面, 点击下一步, ...

  3. 【JMeter_18】JMeter逻辑控制器__吞吐量控制器<Throughput Controller>

    吞吐量控制器<Throughput Controller> 业务逻辑: 他的实际作用似乎跟吞吐量扯不上什么关系.就是单纯的控制控制器下的子节点被执行的次数或被执行比列,该控制器默认为多线程 ...

  4. async/await到底该怎么用?如何理解多线程与异步之间的关系?

    前言 如标题所诉,本文主要是解决是什么,怎么用的问题,然后会说明为什么这么用.因为我发现很多萌新都会对之类的问题产生疑惑,包括我最初的我,网络上的博客大多知识零散,刚开始看相关博文的时候,就这样.然后 ...

  5. #PHP 类的多继承实现之 traits.md

    TRAIT PHP本身是并不支持多继承的,也就是,一个类只能继承一个类,为了满足业务需求,后来有了一些解决方法,例如,链式继承,B继承A,然后C继承B,这样,C就同时继承了AB, 此外还有接口,因为接 ...

  6. synchronized与锁升级

    1 为什么需要synchronized? 当一个共享资源有可能被多个线程同时访问并修改的时候,需要用锁来保证数据的正确性.请看下图: 线程A和线程B分别往同一个银行账户里面添加货币,A线程从内存中读取 ...

  7. [ 头皮发麻 A1 ] 队内赛3 2020 Ateneo de Manila University DISCS PrO HS Division

    都是英语阅读题 但是本菜鸡就过了一题,直接自闭mmp明天开始起床一版题 传送门 B.Riana and the Blind Date 0是闰年?惊了 后来才知道整除被除数可以为0 闰年的计算方法 \( ...

  8. 第一章:开始启程-你的第一行Android代码

    Android 系统为开发者提供了什么? 四大组件 活动(Activity):界面 服务(Service):后台默默运行 广播接收器(Broadcast Receiver):接收.发送广播消息 内容提 ...

  9. JavaWeb网上图书商城完整项目--day02-8.提交注册表单功能之dao、service实现

    1.发送邮件 发送邮件的时候的参数我们都写在了配置文件中,配置文件放在src目录下,可以使用类加载器进行加载该数据 //向注册的用户发送邮件 //1读取配置文件 Properties properti ...

  10. Json序列化帮助类

    public static class Json { public static object ToJson(this string Json) { return Json == null ? nul ...