4

I am getting a CORS issue using request to connect to Neo4j in an Angular2 component:

Response to preflight request doesn't pass access control check. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:8080' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute

How do I set withCredentials: false using request (Typescript)? I'm assuming this will fix the problem. But the request ts file does not list withCredentials in its CoreOptions object. Neither does the Neo4j-Typescript package include this in its Typescript definition.

2
  • 1
    Update: This is an open issue #431 with Webpack dev-server - as @Matteo suggests, the server is not sending back the correct preflight response Commented Apr 24, 2016 at 10:07
  • Update 2: My question fails to mention that I am using the Webpack-dev server middleware. To set withCredentials to false, you must add "Access-Control-Allow-Credentials": "false" and noCredentials: true. to the devServer configuration options. However, see also issue #356 for help on this. Commented Apr 26, 2016 at 12:56

3 Answers 3

1

You can do this by extending the BrowserXhr class:

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor() {}
  build(): any {
    let xhr = super.build();
    xhr.withCredentials = false;
    return <any>(xhr);
  }
}

and override the BrowserXhr provider with the extended:

bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I am injecting this service at the bootstrap level, but still getting CORS error. Apparently The workaround doesn't work when using post with header content-type? I'm pretty sure Neo4j-Typescript library sets a content-type header. Could this be the problem?
1

I had the same issue in my Angular2 application. The problem is that before every request made by the client a preflight request is sent to the server.

This kind of request have a type OPTIONS, and it's duty of the server to send back a preflight response with status 200 and headers set for accepting requests from that client.

This is my solution (with express):

// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');

// Set to true if you need the website to include cookies in  requests
res.setHeader('Access-Control-Allow-Credentials', true);

// Check if Preflight Request
if (req.method === 'OPTIONS') {
    res.status(200);
    res.end();
}
else {
    // Pass to next layer of middleware
    next();
}

As you can see, i set the headers and then fetch if the request type is OPTIONS. In that case i send back a status 200 and end the response.

In this way, the client will be authorized and you will be also able to set your custom headers in all the requests without worrying about CORS anymore.

5 Comments

Thanks Matteo. If Neo4j database server is not correctly responding to preflight requests, I should be able to find this issue in other forums, etc. Could the webpack dev-server be at fault?
Yes, this is surely related to the server not handling the preflight request correctly. Do you have some kind of middleware listening to your requests?
Yes, I think the Neo4j-Typescript library is using Request.js package to communicate with Neo4j REST Api. This is an open issue #431 with Webpack dev-server
I've just read that issue. You can try a similar workaround to the one i've used in express (very similar behaviour). Try to make your webpack middleware send back a res status 200 only to requests of type OPTIONS. If you test it let me know how it acts.
The webpack-dev-server is a node Express server which must be configured through options-- none of which allow for kind of application logic you're implementing here. I'm not sure how to do that using Webpack.
0

If you really want to change withCredentials than you have to provide customized BrowserXhr, see this answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.