本文说明前后端分离后如何继续使用session,示例代码使用vue+springboot,但是原理对所有技术栈都适用。
0.session的原理
维持前后端状态的东西叫:SESSIONID, 存在cookie里,在分离之前,浏览器会在每次请求时带上这个session id, 服务端实际上将用户信息以key-value形式存储,
key为session id,value为用户信息。
分离之后:
在进行session会话管理的时候,前端无法发送cookie到后端,前端每次访问后端都相当于一次新的会话,这样就导致登录后的信息是无法保存的。客户端每一次访问都需要重新登录。
1.前端
在配置中设置withCredentials: true
:
当然,因为每个请求都需要加,配置全局的拦截器里比较好
1 2 3 4 5 6 7 8 9 10 11
| login() { var p = { "userName": "xxx", "userPassword": "xxx" } axios.post(this.baseUrl+'/api/auth/login',p,{ withCredentials: true }).then(function(res){ console.log(res); }); }
|
或jquery ajax:
1 2 3 4 5 6
| $.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } });
|
2.后端
- 服务端的
Access-Control-Allow-Origin
不可以设置为"*"
,必须指定明确的、与请求网页一致的域名(Origin)
- 服务端的
Access-Control-Allow-Credentials: true
,代表服务器接受Cookie和HTTP认证信息。因为在CORS下,是默认不接受的
在springboot里可以这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration public class CorsConfig implements WebMvcConfigurer {
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedOrigins("localhost") .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .maxAge(3600); } }
|
或者使用基础的HttpServletResponse:
1 2 3 4 5 6 7
| @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Max-Age", "3600"); response.addHeader("Access-Control-Allow-Credentials", "true"); }
|
3.使用
现在就可以用 request.getSession()
的经典语句了。
1 2 3
| request.getSession().setAttribute("user", userName);
Object user = request.getSession().getAttribute("user");
|