Token的前后端传递过程如下:
服务端端返回
用户输入账号和密码登录后,服务端会通过加密或者其他逻辑,生成一串标示用户身份的令牌字符串,它就是Token,并返回客户端。
前端获取到后,可以手动存到浏览器的cookie或者localStorage中。
前端携带
登录后,接下来前端在页面的http请求,有些需要让服务端知道你是谁,那么就需要在请求接口时,带上之前存的Token。
那么下面看看传递的方式有哪些:
1.通过url参数传递
//网络请求函数:
function () {
//...
let token = Utils.getCookie(Const.TOKEN);
url += `?_security_token=${token}`;
return ajax(url, payload);
}

2.通过Form Data参数传递
function (params) {
params.opts = params.opts || {};
// 可以做一些token之类的操作
if (store.getters.getToken) {
params.opts.token = store.getters.getToken || '';
}
//...
return ajax(url, payload);
};

3.通过HTTP Request Headers 头部传入到服务器
//axios的处理
axios.interceptors.request.use(config => {
const token = Cookie.get('_security_token') || Cookie.get('_security_token_inc') || '';
config.headers.common["Security-Token"] = token;
return config;
});
//或者自己的网络库
function() {
//...
return ajax(host + params.url, {
data: params.opts,
method: params.method,
contentType,
headers: {_security_token: '02_zMKe_99eah5s0G1'}
});
}

4.通过Cookie(这里就要涉及跨域问题啦)
(1)同域
如果客户端发送的http请求是同域的,那很easy,浏览器会自动帮我们把同域下的cookie添加到请求的request header中Cookie字段中,服务端就会从接收到的request header中提取cookie中的token

(2)跨域
- CORS
如果此时你想到的是用CORS解决跨域问题,该如何解决呢?
一般我们可能会简单粗暴地让服务端将Access-Control-Allow-Origin设为*,但此处没那么简单。
这里需要三部曲:
因为CORS请求默认不发送Cookie和HTTP认证信息,所以如果要把Cookie发到服务器,前后端需要一起配置:
前端需要在ajax请求中将withCredentials设为true,表示允许浏览器携带身份凭证,发送Cookie:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
同时服务端需要设置同意发送Cookie:
Access-Control-Allow-Credentials: true
最后要注意的是,服务端的Access-Control-Allow-Origin不能设为星号,只能设为请求的来源域,否则前面的设置都无效。因为设置星号情况下,浏览器是不会发送cookie的。
CORS部分参考阮一峰老师的跨域资源共享 CORS 详解
- Nginx反向代理
知道通过配置代理可以解决cookie跨域的问题,但是还没有亲自尝试过,自己只是在纯粹跨域的问题中用过代理解决。
比如用vue开发时,在config 文件夹下的 index.js 文件中配置proxyTable属性即可。
proxyTable: {
'/':{
target:'http://xxx.xxx.xxx',//目标接口域名
changeOrigin: true //是否跨域
}
}
作用就是将本地域名的一个请求代理到了目标接口域名下,转发请求。
后面实践过会把此处补上。
- 不同端口下的cookie
不同端口下的cookie可以共享吗?
之前以为cookie完全遵循同源策略,是有跨域限制的,必须协议、域名、端口三个都满足,实践证明它与端口是无关的,只和域名有关,cookie的跨域可以理解为跨域名。其实稍微想一下就可以得出这个答案,因为cookie有一个domain属性,它就是设置域名的,并不涉及到端口,只要二级域名相同,那么就是共享的。
我开启了localhost下8081和8082端口下的两个项目,在8082下设置了一个cookie,发现在8081端口下也共享了这个cookie
document.cookie = "name=oeschger";

