IE 11 request headers issue in case of 302 response code - angularjs

I am making http get request using angularjs and appending header "Authorization" via interceptor to the request, this request goes fine and returns a response with status code 302.
Now when the browser makes the follow up request based on "location" header of the above request response, it removes "Authorization" header.
This is only happening in IE browser and I have verified it on IE11 and it is working fine on Chrome, Firefox, IE Edge.
Please suggest.

This problem occurs where Internet Explorer was caching credentials. We could fix the problem by using the following script:
<script>document.execCommand('ClearAuthenticationCache', 'false');</script>
Or check it out on :
Internet Explorer 11 replaces Authorization header

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.

How to fix this Access-Control-Allow-Headers error

I'm using angularJS for POST from localhost to some API. but I got this error message:
XMLHttpRequest cannot load "...API link..." Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
I can post to the API when I use "Allow-Control-Allow-Origin" chrome extension. But this is just temporary, This way only works when I use this extension on my borwser. But my users got this problem when they use in their own browser.
How to fix this from client side.
I don't think you can fix this issue client side. The API server controls who can access what (using the Allow-Control-Allow-Origin header) so you have to change it there.
The CORS (Cross-Origin Resource Sharing) Request should be enabled in your server i mean in your api like header("Access-Control-Allow-Origin: *");
, otherwise if you still want to access the request from another domain (localhost) if api host is different , in your js code try to use jsonp
here is the documentation
https://docs.angularjs.org/api/ng/service/$http#jsonp

Nginx Web browser CORS Issues

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 :)

angular HTTP auth: not getting browser login prompt

In my angular app, i am trying to do basic HTTP auth.
I send the http get request from angular without any credentials initially, as i assume that when the backend sends a 401 status, the browser would ask me for credentials and would then resubmit the request on its own.
But the browser login prompt is never displayed.
This is the error that i get:
angular.js:11756 GET http://localhost:8080/appName/rest/keys/Keys?batch=0&userName=Test 401 (Unauthorized)
These are the headers i get for response:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:origin, content-type, accept, authorization
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin:http://localhost:3001/
Content-Length:0
Date:Tue, 09 Aug 2016 14:53:26 GMT
Server:Apache-Coyote/1.1
WWW-Authenticate:Basic
I was hoping that the browser prompt would appear automatically when it encounters status 401, but it doesn't seem to be the case here. Am i missing something?
EDIT:
It does not work in Chrome and Firefox, but works in IE, IE displays a login prompt when i try to access the url, and works correctly with username and password, while Chrome directly gives a 401 error.
If i try to access the server url directly from address bar, then Chrome displays the login prompt and asks me for the credentials.
Not sure, but can it be a CORS issue?
Ok, i was able to resolve the issue.
The problem was indeed related to CORS, not in a direct way.
Also, it was working on IE since IE does not respect CORS and will anyways let you access cross origin.
Two things were missing:
Initially i was sending (along with other headers) Access-Control-Allow-Origin : * from the server, for enabling CORS.
Then i got to know this:
Firefox and Chrome require exact domain specification in
Access-Control-Allow-Origin header. For servers with authentication,
these browsers do not allow "*" in this header. The
Access-Control-Allow-Origin header must contain the value of the
Origin header passed by the client.
https://www.webdavsystem.com/ajax/programming/cross_origin_requests/
And then there was an issue related to cross origin browser auth:
By default, in cross-site XMLHttpRequest invocations, browsers will
not send credentials. A specific flag has to be set on the
XMLHttpRequest object when it is invoked.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
This specific flag is withCredentials : true, which needs to be set with the xhr request. I managed to set it with my http request from the angular app, and voila it worked!

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