最近开发一个前后端分离项目,之前都是使用nginx来解决跨域的,都是直接解决问题的,无往而不利。这次突然出了sessionId不一致的问题,百思不得其解,浪费了很多的时间,最终还是解决了,记录一下问题的解决方法。
a.让我们先看看nginx转发的代码
location /api/ { proxy_pass http://127.0.0.1:8088/demo/; } location / { proxy_pass http://127.0.0.1:8000/; }
b.乍一看,将前端和后端转发到了同一个端口下,解决了跨域的问题。果断点击登录,发现成功登录后进入首页,又跳回了登录界面。怎么回事?打开了浏览器的调试界面,无报错,没有问题。
c.再查看后台的输出日志,发现在访问后台的时候每个请求的sessionid都是不一致的,这就有了两种情况:
1.前端的vue是否允许携带cookie,因为大家都知道,sessionId是保存在浏览器的cookie的。
2.浏览器是否允许使用cookie,因为谷歌浏览器有设置是不允许使用cookie的。
排查后发现,vue已经设置了axios.defaults.withCredentials = true,允许携带cookie,并且通过调试器的network,可以看到headers中携带了cookie。response里面有Set-Cookie: JSESSIONID=F51F9C37D5E636F56DF10A2A5E084F7E; Path=/demo; HttpOnly,但是没有sessionId的信息。这样就排除了第二种可能和第一种可能。
d.注意看加粗的set-cookie,我们可以看到set-cookie有一个是Path=/demo,而我们的后台访问路径是/api,这就导致了我们用/api访问后台的时候获取不到sessionid,所以浏览器认不出我们来过了一次,又给我们一个新的sessionid.所以问题是出在了nginx转发的时候。
e.那怎么办呢?解决方法有以下两个:
1.将转发的目录和目标网址设置为一致,如:
location /demo/ { proxy_pass http://127.0.0.1:8088/demo/; }
2.nginx设置cookie的保存路径:
location /api/ { proxy_pass http://127.0.0.1:8088/demo/; proxy_cookie_path /demo /api; }
f.总结:
因为之前的项目的后台都是直接根目录访问的,所以转发为/api也没有问题,但是加了一个/demo后,再转发就不一样了。学无止境,大家共勉。