Node.js设置CORS跨域请求中多域名白名单的方法
CORS
说到CORS,相信前端儿都不陌生,这里我就不多说了,具体可以看看这篇文章。
CORS,主要就是配置Response响应头中的Access-Control-Allow-Origin属性为你允许该接口访问的域名。最常见的设置是:
res.header('Access-Control-Allow-Origin','*');
res.header('Access-Control-Allow-Credentials','true');//允许服务器端发送Cookie数据
然而,这样的设置是最简单粗暴,同时也是最不安全的。它表示该接口允许所有的域名对它进行跨域请求。然而,在一般实际业务中,都希望该接口只允许对某一个或几个网站开放跨域请求权限,而非全部。
那么,聪明的你肯定想着,多域名白名单还不简单吗,写个正则就好啦?再不行,直接配置Access-Control-Allow-Origin属性为用逗号分隔的多个域名不就好了吗?
就像下面这样:
res.header('Access-Control-Allow-Origin','*.666.com');
//或者如下
res.header('Access-Control-Allow-Origin','a.666.com,b.666.com,c.666.com');
很遗憾地告诉你,这样的写法是无效的。在Node.js中,res的响应头Header中的Access-Control-Allow-Origin属性不能匹配除(*)以外的正则表达式的,域名之间不能也用逗号分隔。也就是说,Access-Control-Allow-Origin的属性值只允许设置为单个确定域名字符串或者(*)。
既然我们希望允许的是多个域名,也不愿意使用不安全的*通配符,难道就真不能配置多域名白名单的CORS了吗?
多域名白名单的CORS确实是可以实现的。只是有一点曲线救国的味道。
多域名白名单的CORS实现原理
具体原理可以参考cors库的核心代码:
(function(){
'usestrict';
varassign=require('object-assign');
varvary=require('vary');
vardefaults={
origin:'*',
methods:'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue:false,
optionsSuccessStatus:204
};
functionisString(s){
returntypeofs==='string'||sinstanceofString;
}
functionisOriginAllowed(origin,allowedOrigin){
if(Array.isArray(allowedOrigin)){
for(vari=0;i
实现原理是这样的:
既然Access-Control-Allow-Origin属性已经明确不能设置多个域名,那么我们只得放弃这条路了。
最流行也是最有效的方法就是,在服务器端判断请求的Header中Origin属性值(req.header.origin)是否在我们的域名白名单列表内。如果在白名单列表内,那么我们就把Access-Control-Allow-Origin设置成当前的Origin值,这样就满足了Access-Control-Allow-Origin的单一域名要求,也能确保当前请求通过访问;如果不在白名单列表内,则返回错误信息。
这样,我们就把跨域请求的验证,从浏览器端转移到服务端来了。对Origin字符串的验证就变成了相当于常规字符串的验证,我们不仅可以使用数组列表验证,还可以使用正则匹配。
具体代码如下:
//判断origin是否在域名白名单列表中
functionisOriginAllowed(origin,allowedOrigin){
if(_.isArray(allowedOrigin)){
for(leti=0;i
Ohyeah,简直完美~
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。