Last updated: Mar 7, 2024
Reading timeยท5 min
The error "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'" occurs when the Access-Control-Allow-Credentials
header is set to
true
and the Access-Control-Allow-Origin
header is set to an asterisk *
.
Failed to load https://example.com: Response to preflight request doesn't pass access control check: 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'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
In short, you have 2 options to resolve the error:
Access-Control-Allow-Credentials
header to false
and keep the
Access-Control-Allow-Origin
header to an asterisk *
to allow all origins
to access your server.Access-Control-Allow-Origin
header to a specific origin, e.g.
'http://localhost:3000'
or a list of whitelisted origins that are allowed
to access your server. Note that the origin must specify the protocol, domain
and port.Here is an example of setting Access-Control-Allow-Origin
to a specific
origin.
# ๐๏ธ your domain below, e.g. http://localhost:3000 Access-Control-Allow-Origin: http://example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: POST, PUT, PATCH, GET, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Api-Key, X-Requested-With, Content-Type, Accept, Authorization
CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.
By default, servers only take requests made from applications hosted on the same domain.
If your server is hosted on http://example.com
, for you to be able to make an
HTTP request from http://localhost:3000
, your server has to send the necessary
CORS headers in its responses.
To allow other origins to make requests to your server, you have to set the
Access-Control-*
headers in your server's responses.
Access-Control-Allow-Credentials
header to true
and the Access-Control-Allow-Origin
header to an asterisk *
.The CORS headers are:
Access-Control-Allow-Origin
- which origins are allowed to make requests to
the server.Access-Control-Allow-Credentials
- whether to expose the server response to
the frontend when the request's credentials mode is set to include
. When
credentials mode is set to include
, our frontend will always send user
credentials (i.e. cookies, auth headers) even for CORS calls.Access-Control-Allow-Methods
- which HTTP methods the origins are allowed to
use when making requests to the serverAccess-Control-Allow-Headers
- which HTTP headers the origins are allowed to
use when making requests to the serverWhen an asterisk *
is set for the Access-Control-Allow-Origin
header, any
origin on the internet can access the server.
Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: false Access-Control-Allow-Methods: POST, PUT, PATCH, GET, DELETE, OPTIONS Access-Control-Allow-Headers: *
Access-Control-Allow-Origin
to an asterisk, you cannot set Access-Control-Allow-Credentials
to true
.Here is an example of how you can whitelist multiple origins using the cors package in Express.js.
The concepts apply to any other framework.
const express = require('express'); const cors = require('cors'); const app = express(); // ๐๏ธ specify origins to allow const whitelist = ['http://localhost:3000', 'http://example2.com']; // โ Enable pre-flight requests app.options('*', cors()); const corsOptions = { credentials: true, origin: (origin, callback) => { if (whitelist.indexOf(origin) !== -1 || !origin) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, }; app.use(cors(corsOptions)); app.get('/products', function (req, res, next) { res.json({msg: 'This is CORS-enabled for whitelisted domains'}); }); app.listen(3456, function () { console.log('CORS-enabled web server listening on port 3456'); });
We set credentials
to true
and specified a list of origins we want to
whitelist.
An alternative option would be to check if the client that made the HTTP request
has the Origin
header defined and to allow the specific origin to make a
request.
You can do that by dynamically setting the Access-Control-Allow-Origin
header
on your server to the origin that made the request.
There is an example of how to do this in the "Configuring CORS Asynchronously" subheading of the Express.js CORS docs.
The example uses the CORS
npm package and Express.js, but you could implement
the concept of setting the Access-Control-Allow-Origin
header to the origin
that made the request using any server technology.
const express = require('express'); const cors = require('cors'); const app = express(); const allowlist = ['http://example1.com', 'http://example2.com']; // โ Enable pre-flight requests app.options('*', cors()); const corsOptionsDelegate = function (req, callback) { let corsOptions; if (allowlist.indexOf(req.header('Origin')) !== -1) { // โ set origin to true to reflect the request origin // as defined by the `Origin` request header // or set origin to false to disable CORS corsOptions = {origin: true}; // reflect (enable) the requested origin in the CORS response } else { corsOptions = {origin: false}; // disable CORS for this request } callback(null, corsOptions); // callback expects two parameters: error and options }; app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) { res.json({msg: 'This is CORS-enabled for an allowed domain.'}); }); app.listen(3456, function () { console.log('CORS-enabled web server listening on port 3456'); });
The cors
package enables us to set origin
to a boolean value.
If origin
is set to true
, then the server sets the
Access-Control-Allow-Origin
response header to the value of the Origin
request header and allows the request.
If origin
is set to false
, CORS is disabled for the specific request.
Most servers also allow you to set the value of the
Access-Control-Allow-Origin
header dynamically by using a regular expression
to match the origin.
You will most commonly be OK with just setting the Access-Control-Allow-Origin
header to a single origin.
# ๐๏ธ your domain below, e.g. http://localhost:3000 Access-Control-Allow-Origin: http://example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: POST, PUT, PATCH, GET, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Api-Key, X-Requested-With, Content-Type, Accept, Authorization
The second most common value for the Access-Control-Allow-Origin
header, when
credentials are included, is to specify a list of origins to whitelist.
If a list of whitelisted origins doesn't satisfy your requirements, you can use
a regular expression to dynamically check if the origin should be allowed access
and set the Access-Control-Allow-Origin
header dynamically on your server.
You can also use a function that dynamically sets the value of the
Access-Control-Allow-Origin
header based on some logic that is run on every
request.
To solve the error "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'":
Access-Control-Allow-Credentials
header to false
and keep the
Access-Control-Allow-Origin
header to an asterisk *
to allow all origins
to access your server.Access-Control-Allow-Origin
header to a specific
origin, e.g. 'http://localhost:3000'
or a list of whitelisted origins that
are allowed to access your server. Note that the origin must specify the
protocol, domain and port.You can learn more about the related topics by checking out the following tutorials: