node.js CORS:当凭据标志为真时,不能在 Access-Control-Allow-Origin 中使用通配符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19743396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true
提问by ixaxaar
I have a setup involving
我有一个设置涉及
Frontend server (Node.js, domain: localhost:3000) <---> Backend (Django, Ajax, domain: localhost:8000)
前端服务器(Node.js,域:localhost:3000)<---> 后端(Django,Ajax,域:localhost:8000)
Browser <-- webapp <-- Node.js (Serve the app)
浏览器 <-- webapp <-- Node.js(服务应用程序)
Browser (webapp) --> Ajax --> Django(Serve ajax POST requests)
浏览器 (webapp) --> Ajax --> Django(服务 ajax POST 请求)
Now, my problem here is with CORS setup which the webapp uses to make Ajax calls to the backend server. In chrome, I keep getting
现在,我的问题是 CORS 设置,webapp 使用该设置对后端服务器进行 Ajax 调用。在 chrome 中,我不断得到
Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
当凭据标志为真时,不能在 Access-Control-Allow-Origin 中使用通配符。
doesn't work on firefox either.
也不适用于 Firefox。
My Node.js setup is:
我的 Node.js 设置是:
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8000/');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
};
And in Django I'm using this middlewarealong with this
The webapp makes requests as such:
webapp 发出这样的请求:
$.ajax({
type: "POST",
url: 'http://localhost:8000/blah',
data: {},
xhrFields: {
withCredentials: true
},
crossDomain: true,
dataType: 'json',
success: successHandler
});
So, the request headers that the webapp sends looks like:
因此,webapp 发送的请求标头如下所示:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE'
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=***; sessionid="***"
And here's the response header:
这是响应头:
Access-Control-Allow-Headers: Content-Type,*
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Content-Type: application/json
Where am I going wrong?!
我哪里错了?!
Edit 1: I've been using chrome --disable-web-security, but now want things to actually work.
编辑 1:我一直在使用chrome --disable-web-security,但现在希望事情真正起作用。
Edit 2: Answer:
编辑2:答案:
So, solution for me django-cors-headersconfig:
所以,我的解决方案django-cors-headers配置:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000' # Here was the problem indeed and it has to be http://localhost:3000, not http://localhost:3000/
)
采纳答案by user568109
This is a part of security, you cannot do that. If you want to allow credentials then your Access-Control-Allow-Originmust not use *. You will have to specify the exact protocol + domain + port. For reference see these questions :
这是安全的一部分,你不能那样做。如果要允许凭据,则Access-Control-Allow-Origin不得使用*. 您必须指定确切的协议 + 域 + 端口。作为参考,请参阅以下问题:
- Access-Control-Allow-Origin wildcard subdomains, ports and protocols
- Cross Origin Resource Sharing with Credentials
Besides *is too permissive and would defeat use of credentials. So set http://localhost:3000or http://localhost:8000as the allow origin header.
此外*过于宽松,会破坏凭据的使用。所以设置http://localhost:3000或http://localhost:8000作为允许原点标头。
回答by Hamid
If you are using CORS middleware and you want to send withCredentialboolean true, you can configure CORS like this:
如果您正在使用 CORS 中间件并且想要发送withCredential布尔值 true,您可以像这样配置 CORS:
var cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:3000'}));
回答by Bulkan
回答by Iron shield
try it:
尝试一下:
const cors = require('cors')
const corsOptions = {
origin: 'http://localhost:4200',
credentials: true,
}
app.use(cors(corsOptions));
回答by Squirrl
If you want to allow all origins and keep credentials true, this worked for me:
如果您想允许所有来源并保持凭据真实,这对我有用:
app.use(cors({
origin: function(origin, callback){
return callback(null, true);
},
optionsSuccessStatus: 200,
credentials: true
}));
回答by eriel marimon
(Edit) The previously recomended add-on is not available any longer, you may try this other one
(编辑)之前推荐的附加组件不再可用,您可以尝试另一个
For development purposes in Chrome, installing this add onwill get rid of that specific error:
出于 Chrome 中的开发目的,安装 此附加组件将消除该特定错误:
Access to XMLHttpRequest at 'http://192.168.1.42:8080/sockjs-node/info?t=1546163388687'
from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the
'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
when the request's credentials mode is 'include'. The credentials mode of requests
initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
After installing, make sure you add your url pattern to the Intercepted URLsby clicking on the AddOn's (CORS, green or red) icon and filling the appropriate textbox. An example URL pattern to add here that will work with http://localhost:8080would be: *://*
安装后,请确保Intercepted URLs通过单击 AddOn 的(CORS,绿色或红色)图标并填充适当的文本框将您的 url 模式添加到。要在此处添加的示例 URL 模式http://localhost:8080将是:*://*
回答by Renaud
This works for me in development but I can't advise that in production, it's just a different way of getting the job done that hasn't been mentioned yet but probably not the best. Anyway here goes:
这在开发中对我有用,但我不能建议在生产中,这只是完成工作的另一种方式,尚未提到但可能不是最好的。无论如何,这里是:
You can get the origin from the request, then use that in the response header. Here's how it looks in express:
您可以从请求中获取源,然后在响应标头中使用它。这是它在 express 中的样子:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.header('origin') );
next();
});
I don't know what that would look like with your python setup but that should be easy to translate.
我不知道你的 python 设置会是什么样子,但这应该很容易翻译。

