问题简述:在一个前后端分离项目,后端是SpringBoot,前端是Vue,在Vue上使用Node.js做后端的反向代理,登陆的时候会通过session中是否存在当前登陆用户对象进行判断用户是否登陆。问题就出在这里,每一次请求都拿不到当前登陆的用户信息,都认为是没登录的状态从而报错。
既然是否登陆是通过session来判断的,那我们就需要了解下session是通过什么来识别同一个客户端发送的请求呢?
经过百度我们知道,session识别是否来自同一个客户端发送的请求是通过cookie,在第一次请求的时候,如果session不存在,后端会创建一个新的session对象,并告诉客户端(浏览器)在cookie中写入一个JSESSIONID,之后的每一次请求你都把这个JSESSIONID带过来,我通过这个id来判断并获取属于你的session对象。
于是我分析了下请求,发现每一次请求的cookie都没有发生变化,但是奇怪的是,我在后端进行断点,发现每一次拿到的session都不一样,于是我怀疑是跨域问题,但是事实证明这个方向是错误的,这里就不过多赘述。继续经过一顿折腾我发现了问题的原因所在:
先展示下我Vue反向代理的配置
proxy: {
'/api': {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
pathRewrite: {
'^/api': '/web'
}
}
},
可以看到,因为前后端是2个人开发的,所以前端人员请求接口都是/api开头,而后端配置了context为/web,所以在这里反向代理配置了请求的替换,/api替换成/web
我们分析请求可以发现,在每一次请求之后,因为后端都认为是一个新的请求都创建了一个新的session对象,所以他的请求返回结果会将JSESSIONID通过Set-Cookie带到前端告诉浏览器,你要设置cookie了。但是我发现我的请求cookie设置是如下情况:
Set-Cookie: JSESSIONID=6C923FBF85EB8835CE11A7B61317D9DE; path=/web
看到这里我瞬间恍然大悟,我前端的请求全是/api开头,而后端返回的设置cookie只针对path为/web的有效,这样的话每一次/api的请求依然不会把上一次设置cookie中的JSESSIONID带给后端,后端无法通过JSESSIONID获取session,自然每一次都是新创建session对象,从而导致登陆一直失败的问题。
所以解决办法就是要么前端修改要么后端修改,把请求路径统一,修改后的反向代理配置为:
proxy: {
'/web/api': {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
pathRewrite: {
'^/web/api': '/web'
}
}
},
问题迎刃而解。