I understand it determines the headers the client can access from the server response, however, I am confused on exactly when this is applied. Does it determine the headers for every cross-origin request that is allowed by the Access-Control-Allow-Origin header?
To test this I setup a test site in express and put the following code in it:
app.get('/',(req,res)=>{
res.set('Access-Control-Allow-Origin','https://www.google.com') // to be able to make a cross-origin request
res.set('foo', 'bar') //custom header that should get filtered because i havent set the access-control-expose-headers header
res.send('Hello world')
})
Based on my understanding of this, because I haven't set any special Access-Control-Expose-Headers header in the response, the client should only be able to access CORS-safelisted response headers and therefore should not be able to see my foo header.
But when I'm at https://www.google.com (Which I allowed for CORS with the Access-Control-Allow-Origin header) and send a GET request to my test site I see the foo header in the response just fine. Why is this? Could someone explain how this works or at least point me in the right direction? Thanks in advance.
I figured it out. The reason I was receiving my custom header was that I was reading the response headers in the Network tab of Chrome Dev Tools. When I run this script:
fetch('http://127.0.0.1:3000/')
.then(r => {console.log(response.headers.get('foo'))})
It prints null. So the header is not actually accessible to the fetch request, only to the Dev Tools.
Related
Getting response headers and I want to expose one of the header from it. For eg, x-cloud-trace-context this header should visible in the browser response body.
I tried with exposedHeaders using CORS but still not getting it on the browser and this leads to preflight mode.
Any help would be highly appreciated.
I want to see in Node Exprees enviroment all the headers that are sent to the client
But when i see do this:
app.get("/", (req, res) => {
console.log(res.getHeaders());
});
i only see this :
At the time you're looking at the outgoing headers, those are the only ones that have been added so far. The rest will be added by the code that sends the actual response or by other middleware.
If you want to see all the headers that were eventually added to the response before it was sent, you can monitor the finish event and THEN look at the headers:
app.use(function(req, res, next) {
res.on('finish', () => {
console.log(`request url = ${req.originalUrl}`);
console.log(res.getHeaders());
});
next();
});
This will sometimes not include the date, content-type or content-length headers unless they are specifically set by the sending code. This is because if these are not set by the sending code, then the HTTP library adds these headers at a lower level as it is sending the headers and thus res.getHeaders() does not retrieve them and never knows about them.
Edit: I overlooked your first screenshot... Are you using any middleware? It looks like you're using the CORS middleware, at least - which is why you are showing more headers than the defaults..
It looks like Node/Express sends a Content-Length header when it can..
The Date header is mandatory per the HTTP spec, but it looks like you can change that behavior in Node/Express - I'm guessing by default Node/Express sets that value to true.
I did test setting res.sendDate = false and the date header was not sent, so it looks like that header is set by default for you, most likely as the last step in the response?
With res.sendDate = false;
Without setting res.sendDate (aka the default):
All in all, I'm assuming the headers you don't see when you console.log(res.getHeaders()) are set by Node/Express by default..
I wasn't able to find anything in the docs about default response headers (outside of the Date header), but it's possible I overlooked something. The Express docs don't have anything on it as they just use the built in http module from Node.
This question already has answers here:
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 4 years ago.
I was working on a AWS project, and noticed that in order to allow CORS, my seniors had set headers property Access-Control-Allow-Origin, in response. So whole response was like:
module. exports.handlerFunction = async ( event, content) => {
// code here for DB calls and other logic
return {
headers: {
"Access-Content-Allow-Origin" : "*"
},
statusCode: 200,
body: result
};
}
And my thoughts were, how is it even working and allowing CORS?. What if we didn't wanted origin to perform any operations and had done "Access-Content-Allow-Origin": "https://example.com".
Since we are setting this in response, so the origin which was not supposed to do anything and just return, now have done everything and then responded with error of CORS. I asked my seniors, "How this is working and How CORS work?", the response was its browser property and browser send a pre-flight request and check for CORS. But we check for CORS at end, once every thing is done, how did pre-flight request skipped all our checks DB and API call and just landed at end and check for response headers. They had no answer and said same pre-flight concept. I asked next question "browser have pre-flight concept to check for CORS, what about postman, cUrl requests and then API call via various programs like node-fetch, request, https API call module in NodeJs do they also make pre flight call".
Also when I was creating my NodeJs express Server application, I used cors.js a NPM module. With that I checked for CORS before entering into any API function, on entry of every call and only allowed permitted source to enter. Code is like:
const CORS = require('cors'),
express = require('express');
const app = express();
let allowedOrigin = ['https://example.com'];
let corsOps = {
origin: (origin, cb) => {
if (allowedOrigin.includes(origin))
cb(null, true);
else
cb(new Error('Not allowed'));
}
};
app.use(CORS(corsOps));
This checked before calling any function and not on response.
I searched a lot about this behavior and have seen multiple examples of using CORS in headers, How does it even work in headers?.
For me it's my backend that stops call and check who is calling backend API.
How can someone who is making requests set property in headers and backend open its access to anyone, just by seeing headers property and not checking source that called?
When browsers execute an AJAX call, they first check if the target origin matches the current origin a.k.a. window.location.origin. If not, they check if the target origin accept window.location.origin as source of a CORS request. If not, the browser shows the infamous No 'Access-Control-Allow-Origin' header is present on the requested resource. error message.
If the request can be made, the browser includes the Origin header in the HTTP request with the value of window.location.origin.
There are multiple ways to set up the CORS policy in the backend:
Accept all origins with the wildcard
Only accept a preconfigured set of origins
Dynamically take the value of the Origin header as the value of the "Access-Content-Allow-Origin on a request by request basis
In the last case, the origin may be obviously spoofed like so:
curl -H"Origin: https://www.example.com" https://api.example.com/some/path
Whether or not a server should serve a request should not obviously depend on the Origin header but on other factors such as an Authorization header or an appropriate authorization Cookie; validity of request parameters etc.
Ionic 2
I am using login provider but when i set the access control to
res.header('Access-Control-Allow-Origin', '*');
It is not working
But it works properly when i use
res.header('Access-Control-Allow-Origin', 'http://localhost:8100');
It is working
but now i want to deploy my app up on phone device i need to set it to wild card res.header('Access-Control-Allow-Origin', '*');. since my app on phone not working on http://localhost:8100 anymore
Anyone can help me solve this problem ?
If you are making a preflighted request then the wildcard is forbidden in the Access-Control-Allow-Origin header.
You can read the Origin request header in order to find out the origin. Then you can test it against a list of allowed origins (you could also assume that any origin is OK, but for a preflighted request there is a good chance that complete public access would be a security risk). Finally you can copy it into the Access-Control-Allow-Origin response header.
How is your HTTP request from your app looks like?
Look for "Types of CORS requests" in this article.
If your HTTP request is a simple one, i.e.
Method is HEAD, GET, or POST
Only have these headers
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type of application/x-www-url-encoded, multipart/form-data, or text/plain
If your HTTP request is a simple one, preflight is not needed. And Access-Control-Allow-Origin with * is accepted by the mobile app.
Otherwise, a preflight request will be made (i.e. OPTION request) and Access-Control-Allow-Origin of * will be ignored. It must be fully specified like http://localhost:8100.
I am developing an ajax form update on localhost in express.js for learning express.js
The origin in header is alway set to be null by browser for CORS request (tried: firefox, chrome and safari)
Question:
1. "Origin: null" in request header is not the problem of express.js. Is this correct?
Why they(is it the browsers?) set the Origin to null? I think it should look like this one: "localhost:3000/myproject/test/form.html"
Should I use jquery ($.ajax() or $.ajaxSetup()) to set the origin, before calling ajax on localhost?
How to make the origin in header reflect the real situation?
Here is the screenshot: [...the screenshot is gone now...]
I read the following article about the CORS. The origin in header is null, which is not explained. Please help.
http://www.html5rocks.com/en/tutorials/cors/
"The first thing to note is that a valid CORS request always contains an Origin header. This Origin header is added by the browser, and can not be controlled by the user."
How to allow CORS?
The Origin header is null because you are making the CORS request from a local file (I bet the url starts with file://). In order to get a "normal" origin, you need to host the client file on a web server and access that file using http or https.
Also note that the Origin value is set by the browser and can not be overridden by client JavaScript code.
(P.S. I wrote that HTML Rocks article, I'll make a note to add a section about null Origin)