问题描述
自己在写一个前后端分离的项目时,涉及到用户的登陆信息的保存。但是前后端分离的跨域访问,造成每一次前端的请求都会被后端作为新的访问,无法通过session保存。
网上百度很久,看见有人说可以通过设置withCredentials为true,让请求头携带Cookies,由此来保证session一致。我用的是spring boot 和 jquery的Ajax(个人对于前端框架没怎么学习),具体看代码:
这是后端配置类,allowedOrigins("*")也有人说必须写对应的源地址,也就是前端部署的地址,反正我是都试过,没啥区别,也有可能因人而异(苦笑)。
@Configuration
public class CROSConfig extends WebMvcConfigurationSupport {
@Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
super.addCorsMappings(registry);
}
}
然后是前端代码,我省略了一些与具体逻辑相关的,主要看一下使用方法
$.ajax({
url: "",
type: "POST",
dataType: "json",
xhrFields: {
withCredentials: true
},
crossDomain: true,
contentType: "application/json",
data: JSON.stringify(params),
success: function (res) {
}
}
});
然后就是喜闻乐见的没有任何用,每一次访问,都会产生一个新的session。并且从浏览器调试里看请求头,发现一直少了Cookies,尽管设置了withCredentials为true。口说无凭,看图:
一直查了好久,都没办法解决,后来干脆换了vue来写前端(因为看好多人都是vue+axios然后照着上面一配置就没问题了,我还能说什么呢)。
但是就是因为这么一换,我发现vue+axios确实可以实现,但是也需要配置一个东西,叫做devServer代理。想到代理,我就明白了,这实际上根本不是直接通过配置来解决跨域的session不一致的问题。不说了,上图片:
Cookies是有了,但是,前端访问的地址和自己的地址一样,也就是说不跨域了。
所以,出现这种情况的根本原因是,withCredentials,在同源的情况下,不管是true还是false,都是无效的,请求头中都会设置Cookies。只有在跨域的情况下,这个设置才会有效果(Maybe)。
解决方案(设置代理,绕过跨域访问问题)
那问题明了,靠直接配置的方法既然没用(反正我是),就曲线救国吧。原理已经知道了,就是靠设置代理来绕过跨域携带cookies的问题。
我一直使用的是nginx来部署和测试前端代码,nginx本身就可以很方便的实现代理,那我也就不用再重新去搞vue了。
放一波超简单的nginx配置文件
server {
listen 80;
server_name www.test-crowdfunding.com;
location / {
root E:\fontweb;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /api/ {
proxy_pass http://localhost:9090/;
}
}
最后一个proxy_pass配置就是至关重要的代理配置,目标地址是我的后端项目。
成功解决:(要注意访问地址的改变噢)