Nginx Web browser CORS Issues - angularjs

I'm working on an AngularJS Application which uses an external API and I got a weird issue (CORS). I made a lot of research that does not fix the issue.
When I hit my API the preflight request is good (status 204 No-Content),
but when the server responds with a another status code than 2xx (200, 204 etc...) I got the CORS issue.
If my server send back 2xx as status code is alright we have no CORS issue but if another status code is sent here is the problem.
API :
Sylex(PHP Framework) running under Nginx
Front application :
AngularJS - using webpack
XHR VIEW :
Console CORS Error :

After a day of search I figured out where the CORS was coming from.
The Nginx configuration was ok. It was the API.
During the preflight request (OPTIONS) the server let passed the request because NGINX allowed the origin and header (access-control-allow-origin, access-control-allow-headers),
but when the API sends back the response the headers were not set up.
I fixed it by adding the access-control-allow-origin and access-control-allow-headers to the response.
IMPORTANT: I figured out data weren't recoverable in the response with the 200 status code on the webbrowser. To fix it remove the headers added in the others responses (5xx, 4xx, etc..)
(I don't know if its just in my case)
I haven't developed the API that's why it takes me a day to figure it out. Hope I will help someone with this use case :)

Related

(NodeJS / AngularJS) POST request with 'x-auth' token to server, but token seems to get lost in preflight (no error though)

Background
I have a simple NodeJS server hosted on localhost/Heroku which handles JWT authentication for adding data to the registered user amongst other (unrelated) things.
Here's the GitHub: https://github.com/mlee93dev/pw-keychain-server
I also have a simple Angular2 client on localhost/Heroku for this server:
https://github.com/mlee93dev/pw-keychain-app
Currently, I have my JWT access tokens configured to last only 5 seconds in my server for development purposes.
I have my CORS stuff configured to the best of my knowledge as shown below in server.js:
CORS configuration pic
The Problem
On Postman I test the POST request and I get the expected response - a JWT expiration error:
Postman POST pic
However I don't get the same response on my client - rather, I get a 'JWT must be provided' error:
Client POST pic
As you can see in the pic above, I know I'm actually attaching a token as I console.log it. Here's a pic of the code:
Client POST code pic
So what's confusing me more is that my DELETE request (for logging out) also implements the same x-auth token to request code, and it works in both Postman + client, as seen here:
DELETE error response
DELETE code
So yeah, I'm pretty confused. My guess is I have to configure my CORS some more to allow x-auth header on POST requests specifically somehow? Even though I think it should do that already with my current configuration.
You are providing the body in post request instead of headers.
Angular POST request
So in your post request just do the following
this.http.post(yoururl, {},{headers:new Headers({'x-auth':token})})...
And it should work.

Allowing CORS only for my domain?

I have an AngularJs website and when I am trying to post data then when I am opening my website without using www then I am getting
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
Otherwise, I am not getting any error.
I tried to search and found that I should implement CORS on my backend which is in NodeJs but can anyone please tell me how can I only implement CORS Headers such that for both www and without, it would work but for any other domain trying to access my API must result in preflight error.
I am trying to do this because I read here which-security-risks-do-cors-imply that allowing all domains can increase security overhead for my website which I do not want.
Thanks.
I'm afraid this is not something you can tweak just in your client-side code. In order for cross-origin requests to work, you need to set an http response header: it's the server, who serves the resource, who will need the change, not the client side code from angularJs.
I believe that you should update your question stating what your server side language is and how are you handling http requests in the server side. As far as I know, just adding a header like:
Access-Control-Allow-Origin: http://client.domain.com
In your responses will do the trick. Where client.domain.com is the domain of your client, angularJs application.

OPTIONS Error using twitter API (400)

For my personal website, I'd like to create a page summarizing my social presence.
I used Postman to make sure all my queries are valid.
So I made simple call to get my last post on twitter.
Everything works find on Postman, so there isn't any Authorization issues.
But when it comes to implement it on my client (using AngularJs ), I'm getting this error:
OPTIONS https://api.twitter.com/1.1/statuses/user_timeline.json?user_id=1106474965 400 ()
XMLHttpRequest cannot load https://api.twitter.com/1.1/statuses/user_timeline.json?user_id=1106474965. Response for preflight has invalid HTTP status code 400
I know it may be related to How does Access-Control-Allow-Origin header work? but I can't configure the server as I subscribed a shared hosting
(One.com).
I tried to reset my $httpProvider default values in vein.
It seems Twitter API doesn't support CORS headers, and that's why your preflight tests are failing:
https://twittercommunity.com/t/will-twitter-api-support-cors-headers-soon/28276

Status code 405 (Method Not Allowed)

I'm new to AngularJs and Ionic. Building a schedule app just to practice so please go easy on me.
I don't know why I'm getting this 405 response. I tried to do a GET request with postman with the same information and it worked, but it doesn't work with my AngularJs code.
NOTE: I changed my access token (From UW) for safety.
Here's postman:
Here's my angular service:
and here's the error I'm getting when I run the ionic app:
You have a cross origin policy problem.
Add these headers to your webserver and you should be all set:
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Don't forget to modify scope to suit your need.
== update ==
I just checked the link. The server is IIS 8.5
So I think this link you may find it helpful: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
A 405 is a problem with the server angular is trying to talk to. Essentially, the request you made was matched to a route, but your server will not allow that route to execute.
Specifically, for your problem (and this is just my best assumption) ws.admin.washington.edu requires users to sign in. Your request is not authenticated.

Whenever a CORS $http request fails, the response returned is always 0

this is a similar question to this post in SO.But the answer provided here cannot be applied in my case as i cannot change the response headers from server.
Suppose an http POST to a different origin. This implies CORS, including a CORS preflight exchange. Now suppose the OPTIONS request returns a 503 service unavailable error due to a server problem. In this case the error handler gives ""for data and 0 for status instead of giving me the status code 503 and the text:service not available. An example of this scenario is illustrated in the below image.
I am using angularjs $http and i know in the response there are no CORS header if such errors happen.and i cannot change it.
Is there any way i can receive the proper error code and the text in my rejection object.
This is not an issue of AngularJS / $http but it is the behavior of the browsers and their XMLHttpRequest object: If the CORS request fails, the browser does not give any information back to the caller.
Before I got this understanding, I also though it to be an AngularJS issue and I raised an open issue on github of Angular -> with the corresponding comment.
https://github.com/angular/angular.js/issues/13085#issuecomment-148047721
So I think there seems no other way to solve this as to add the Access-Control-Allow-Origin response header also on the proxy / load balancer in case of 503.
Edit:
If your load balancer is a HAproxy, the following may help you too:
HAproxy: different 503 errorfile for OPTIONS and POST methods
It shows how to let HAproxy anwer the CORS requests autonomous.

Resources