最近日常开发的项目在发布到测试环境时遇到登录session不一致的问题,特此将排查过程记录一下:
问题描述:
项目用到了登录校验,用户登录之后,将数据库查询出来的User对象放入Session中保存,当发其他需要校验登录的交易时,使用拦截器配合SpringAOP进行登录校验,校验逻辑很简单,就是将之前登录放入Session的User对象取出判断是否为空,如果不为空则继续执行后面的逻辑代码,为空则返回用户未登录,本地环境测试了一点问题没有,但是上了环境之后,用户登陆完成之后发别的交易总是返回用户未登录;
问题排查:
1、首先本地测试没有问题,上环境之后有问题,唯一的区别是上了环境之后,环境上使用了nginx方向代理,并且通过浏览器发现存入Session的SessionID和取Session的SessionID不一致;
经过百度得出nginx方向代理需要设置下cookie复制。配置伪代码如下:
location /aaaaa/bbbbbb { #代理跳转的路径 proxy_pass http://localhost:8080/bbbbbb; #proxy_cookie_path 后面的两个斜杠表示将源访问地址的“/”路径的cookie复制到目标地址的“/”路径。 proxy_cookie_path /bbbbbb /aaaaa/bbbbbb; }
2、改了之后发现问题并没有解决,后面才发现一个大坑,因为我登录之后直接将数据库返回的User对象放入了Session,伪代码如下:
//查询数据库,返回User对象 User u = userService.checkLogin(user); session.setAttribute(USER_IN_SESSION,u); //session过期时间设置,以秒为单位,即在没有活动30分钟后,session将失效 session.setMaxInactiveInterval(30 * 60);
可以看出,我这里直接将User对象放入Session中的,而不是往Session中存入JSON串什么的,并且我这个User对象并没有序列化, z之后给对象implements Serializable 序列化之后,问题解决,真的是尴尬呀,后面还是建议大家在创建数据对象的时候都序列化一下~~~