I have a socket.io service that different devices want to connect to that, and because of it, it's very important to me that my socket.io service allows all origins (even when a client doesn't set any origin in the header) to connect to that, this is my io (server-side):
const server = http.createServer(app); // app is express app
const io = require('socket.io')(server,{
allowEIO3: true,
cors: {
origin: '*',
credentials: true
},
});
and this is my client:
const socket = io('http://localhost:4855/', {
timeout: 60 * 1000,
reconnection: true,
forceNew: true,
query: {
authorization: `Bearer ${token}`
},
// extraHeaders: {
// Authorization: "ksi",
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Credentials": true
// },
// Headers: {
// "Access-Control-Allow-Origin": 'http://localhost',
// },
// headers: {
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Credentials": true
// }
});
socket.connect();
ERROR MESSAGE: from origin 'http://localhost' 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.
CodePudding user response:
The error is pretty clear.
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'.
And you said:
origin: '*',
So you have to return the actual origin and not the wildcard.
The documentation says:
All options will be forwarded to the cors package. The complete list of options can be found here.
Which, in turn, says:
origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:
- Boolean - set origin to true to reflect the request origin, as defined by req.header('Origin'), or set it to false to disable CORS.
- String - set origin to a specific origin. For example if you set it to "http://example.com" only requests from "http://example.com" will be allowed.
- RegExp - set origin to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern /example.com$/ will reflect any request that is coming from an origin ending with "example.com".
- Array - set origin to an array of valid origins. Each origin can be a String or a RegExp. For example ["http://example1.com", /.example2.com$/] will accept any request from "http://example1.com" or from a subdomain of "example2.com".
- Function - set origin to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as callback(err, origin), where origin is a non-function value of the origin option) as the second.
Since you want to allow any origin, you can't use a string or an array.
The other options would all work, but the simplest is the boolean.
cors: {
origin: true,
credentials: true
},
CodePudding user response:
If your backend relies on the Bearer authentication scheme (as your code snippet suggests) and not on cookies, you do not need to use credentialed requests or to allow credentials in your CORS configuration. You can keep using the wildcard (*
) to specify the allowed origins; you'll also need to explicitly allow the Authorization
request header:
cors: {
origin: '*',
allowedHeaders: ["authorization"]
}
This instance of Jake Archibald's playground may be enough to convince you.
The CORS configuration above is secure insofar as cross-origin attackers cannot forge authenticated requests on behalf of their victims.
If, on the other hand, your backend server relies on cookies, you need to use credentialed requests and allow credentials in your CORS configuration. However, the CORS spec forbids the use of the wildcard in conjunction with credentialed requests. It may be tempting to allow all origins with credentials (as recommended by Quentin), but that amounts to voiding the protection provided by the Same-Origin Policy and exposes your users to cross-origin attacks. More details in James Kettle's post on Portswigger's website.