Search code examples
httpcorsxmlhttprequesthttp-headers

How does a server know a request is sent with credentials?


I've been having a problem that just cropped up when requesting a resource from another server through my website.

I request the resource (a PDF file requested through Range Requests). The browser (Chrome in this case) sends an OPTIONS request to the server. The server returns 200 from the OPTIONS, but one of the headers is - Access-Control-Allow-Credentials: true Since the server exposes the wildcard * for the Access-Control-Allow-Origin response header, Chrome then (I think) throws out the following responses from the server and gives me an error saying that the server can't expose the wildcard if the request is made withCredentials = 'include'.

Now, I'm not setting the withCredentials flag anywhere in my code that I can see and I can't seem to find out how the server knows if a request is sent withCredentials. My cookies aren't sent with the OPTIONS or following GET/PARTIAL CONTENT requests. There's no other special headers in the request that I can see.

So,

  1. How does the server know and how can I tell on the client side wither credentials are set to include?

  2. If I'm not setting credentials on my side, what could be causing Chrome to think that the mode I'm using is withCredentials = 'include'?

  3. Should the server be sending back the Access-Control-Allow-Credentials: true header on ALL requests after the OPTIONS?

Solution

    1. How does the server know and how can I tell on the client side wither credentials are set to include?

    The receiving server doesn’t know anything about the client-side withCredentials setting. The server just receives some form of credentials in the request, or doesn’t. And as far as the CORS protocol goes, the receiving server doesn’t change its behavior based on whether the request includes credentials or not. The receiving server either just sends back the Access-Control-Allow-Credentials: true response header, or doesn’t.

    1. If I'm not setting credentials on my side, what could be causing Chrome to think that the mode I'm using is withCredentials = 'include'?

    The answer to that is, it’s subjective — it depends on who the server admin intends the response for. But best practice is, you probably only want to send back Access-Control-Allow-Credentials: true to particular origins that you know and explicitly want to allow. That’s why the CORS protocol has the restriction that it won’t allow your frontend code to access a response if the request has credentials and the response has the Access-Control-Allow-Origin: * (wildcard) header value.

    1. Should the server be sending back the Access-Control-Allow-Credentials: true header on ALL requests after the OPTIONS?

    Chrome would only think that if the mode actually really is withCredentials = 'include'. So either some part of your client code is actually setting withCredentials = 'include' — or else, withCredentials = 'include' isn’t actually getting set all but you for some reason just think it is.