CORS: credentials mode is 'include'

Richard Bailey picture Richard Bailey · Mar 15, 2017 · Viewed 132.1k times · Source

Yes, I know what you are thinking - yet another CORS question, but this time I'm stumped.

So to start off, the actual error message:

XMLHttpRequest cannot load http://localhost/Foo.API/token. 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:5000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

I'm not sure what is meant by credentials mode is 'include'?

So when I perform the request in postman, I experience no such error:

enter image description here

But when I access the same request through my angularjs web app, I am stumped by this error. Here is my angualrjs request/response. As you'll see the response is OK 200, but I still receive the CORS error:

Fiddler Request and Response:

The following image demonstrates the request and response from web front-end to API

Fiddler

So based on all the other posts I've read online, it seems like I'm doing the right thing, that's why I cannot understand the error. Lastly, here is the code I use within angualrjs (login factory):

enter image description here

CORS Implementation in API - Reference purposes:

Method 1 used:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*")
        {
            SupportsCredentials = true
        };
        config.EnableCors(cors);
    }
}

Method 2 used:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

}

Many thanks in advance!

Answer

geekonaut picture geekonaut · Aug 17, 2017

The issue stems from your Angular code:

When withCredentials is set to true, it is trying to send credentials or cookies along with the request. As that means another origin is potentially trying to do authenticated requests, the wildcard ("*") is not permitted as the "Access-Control-Allow-Origin" header.

You would have to explicitly respond with the origin that made the request in the "Access-Control-Allow-Origin" header to make this work.

I would recommend to explicitly whitelist the origins that you want to allow to make authenticated requests, because simply responding with the origin from the request means that any given website can make authenticated calls to your backend if the user happens to have a valid session.

I explain this stuff in this article I wrote a while back.

So you can either set withCredentials to false or implement an origin whitelist and respond to CORS requests with a valid origin whenever credentials are involved