前言
在做项目时,在登录验证码生成环节,后台生成验证码图像返回给前端,并将验证码置于session
,用户填入验证码后传入后台并验证。
但在实验时发现,由于前后端分离项目存在跨域问题,session
不再相同,通过输出 sessionId
也可以看出,不同请求到达服务端时sessionId
是不同的,故需要考虑如何解决Session
不一致的问题。
正文
CORS
首先简单讲下CORS。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
其中关于CORS的请求头参数主要有:
- Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
- Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下为fasle,即Cookie不包括在CORS请求之中。(为了确保session的正常使用,需要将此布尔值设为true)
- Access-Control-Expose-Headers
该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
综上,为了sesion的使用,需要开启Credentials
前端开启Credentials
由于前端请求使用的是Vue中的axios,故在axios请求上统一设置Credentials,具体如下:
axios.defaults.withCredentials = true
当然,如果使用的是ajax,也可如下设置:
$.ajax({
....
xhrFields: {
withCredentials: true
},
crossDomain: true,
...
以上,前端设置完成。
服务端开启Credentials
相应地,对于客户端的参数,服务器端也需要进行设置。
对应客户端的 xhrFields.withCredentials: true 参数,服务器端通过在响应 header 中设置 Access-Control-Allow-Credentials = true 来运行客户端携带证书式访问。
具体如下:
首先添加一个全局拦截器:
package com.h