HTTP Requests with cookies on chrome extension - angularjs

I have been several days trying to understand how a chrome extension is working when a HTTP request is made.
I am using YARC (Yet Another Rest Client) Chrome extension. But I guess it works same for all. Even Postman.
First thing I see is when I make the request if I am using an http traffic viewer like fiddler, I can see the host is the same I am making the request (Like www.google.com) and if I make an Ajax request or a php request the host is the same i have the script (like localhost).
The other thing is that I am making a POST request to a site to make a login that set a cookie. If I make it with the chrome extension, the cookie is set on my browser and then I could navigate normally on that page and the cookie is set and I am logged in. If I make this post with Ajax or PHP i´ts impossible to set this cookie because my host is in a different domain (localhost).
I can see I could make a submit post for this, but then I got redirected after the submit and it´s impossible to avoid that. I would like to manage the response like the extension as it was an Ajax call.
The main thing I see here is that thy host is always on same domain and this could avoid all this problems. But HOW? Looking for YARC code I can see they make this request as a regular http angularjs, it means Ajax I am almost sure. Anywhay not even trying with angularjs http I can get this to work.
What I actually would need to do is how this Chrome extension could make this and how to set this cookie when I make this POST, I mean, the Host set the cookie on their own domain, cause I can get the cookie but not to set it and I know it is impossible from a different domain.
Thanks in advance for all your help.

Related

App Engine different response on browser vs postman

I have a nodejs express server running on app engine.
If i make a GET request to https://astral-pursuit-252600.appspot.com/users in the browser it works fine to say unauthorized (401).
If I do the same GET request in postman it returns 400 bad request.
Is there any obvious reason why this is occurring?
This is a known issue with postman. This tool sends certain headers by default that you cannot remove. App Engine does not like them for some reason. I had to use the Insomnia tool instead which does not include default headers.
The first thing that I can think about is that, in order to do an API call, you need to use an API key in your request. You should create one, after that you need to obtain an access token. Your requests should be send to an address like https://astral-pursuit-252600.appspot.com/users?key=YOUR_API_KEY and include in your request a header to contain the access token. Something like this : --header 'authorization: Bearer YOUR_ACCESS_TOKEN'.
In order to do that I do not think you need to change manually each request, but you need to change some POSTMAN settings. You can find here a guide with exactly what setting should be changed for this use case.
You can see more details about this topic and a more detailed guide for doing an API calls here.
In case this was not the issue, could you please provide me your POSTMAN settings? I am pretty sure this is about the way POSTMAN does the requests anyway.

How is "No 'Access-Control-Allow-Origin' header" a server issue if I can turn on a CORS extension and it works?

I access a server that I can change in any way. It is only available to me.
GETS / POSTS work in curl, but I get an error in my angular web app
I read a ton of posts about this, and after nothing seemed to work, I installed the CORS extension to Chrome, added *://*/*, and I have to turn it on anytime I'm trying to access the server. But it works.
Most of the posts say this is because the server does not allow access from outside sources. So I did some more digging and found the W3 CORS enabled site, that specifies a filter must be added.
However, when I get the error, I can open the network panel and see that the response came back exactly as I was expecting, so why did I get an error?
This makes it seem like Chrome is not allowing access.
Why must the server be changed to allow this?
Does this mean anyone with this chrome extension can access my server?
It seems like it should be possible to configure a header in my $http.get that would allow this, but everyone keeps saying its the server...
Cross domain calls are not allowed by default. When the browser makes a call to a website or Web-API sitting on a different domain than the domain opened on the browser, it includes a HTTP header "Origin" in the request. The server looks at this header and if it's white-listed it includes the header Access-Control_Allow_Origin in the response. All this happens in a pre-flight request using HTTP Options method before the actual GET/POST call. So for the CORS to work the server has to allow the client domain, so the browser can make further calls.

$http.post cross domain request not working in Internet explorer (Network Error 0x80070005, Access is denied)

When I make an $http.post request and set the "withCredentials" property to true.
My request works fine in Chrome and Fiefox. However, I'm getting the error below in IE:
XMLHttpRequest: Network Error 0x80070005, Access is denied.
I noticed that if I enable the "Access data resources across domains" setting in IE, The error gets resolved. However I need to find an alternative solution because I can't ask the users to enable that setting obviously.
I noticed that a $http.get request to the same domain is working in IE with no issue, the issue is only with the $http.post request, the Options request is getting a 500 internal server and I see the request and response headers below:
Note:
I do have the necessary custom headers, and I can see them in Chrome when the OPTIONS request succeeds. The headers that I see in Chrome are listed below:
Could you please let me know if I'm missing something that would make the request work in IE without having to enable Access data sources across domains?
Internet Explorer 9 doesn't support cookies in CORS requests. The withCredentials property of the $http arguments attempts to send cookies. I don't think there's any way to fix it with headers. IE10+ should work by default, just be sure that you are not in compatibility mode. CORS isn't fully implemented in IE10 either, but the type of request you are trying to do should work.
You didn't mention what the nature of your web app is, but it impacts the type of workaround you will need for IE9. If possible, see if you can refactor your code to use a GET request instead (again, I don't know what you are trying to do via AJAX so this may be impossible).
You may be able to use Modernizr or something similar to detect if the browser supports CORS. If it is not supported, send the request without AJAX and have a page refresh.
Another alternative if you really want to use AJAX is to set up a proxy on your web server, i.e. the server on the same domain. Instead of making the cross-origin request directly, you make the AJAX request to your same-origin server, which then makes the request to the cross-origin server for you. The server won't have CORS issues. This solution assumes, of course, that you have some server-side scripting going on such as PHP, Node or Java.

Is a single Cookie Based API for multiple frontends possible from a CORS perspective?

I originally wrote an REST API to work with a previously written mobile app. The mobile programmer requested from me to generate an auth_token on login that he will pass as a header on each request that needed authentication. This API runs at api.example.com.
Later on, I was commissioned to write an AngularJS app that communicates with this API, so I had to use Access-Control-Allow headers on the backend for OPTIONS requests to be CORS compatible CORS so my browser allows the connection (looks like iOS does not look for this headers). This app runs at one.example.com.
Now, I have to write a second AngularJS app that will run at two.example.com and there's a third being planned for the near future at three.example.com.
My problem is that my Access-Control-Allow-Origin header looks like this:
Access-Control-Allow-Origin: http://one.example.com:80
* is not allowed, nor I'm able to set this header to more than one origin. So as far as I can see I have two solutions:
Implement token-based authentication in parallel to the current cookie-based one. I'm thinking on this. This will of course take some time I'm willing to save.
Send the requester a header or param to the API endpoint identifying the app on the OPTIONS request and server-side, produce the CORS headers accordingly. I don't even know if it's possible and this looks nasty for even thinking it.
Any better ideas?
If they have the same origin, example the same domain (example.com) or the same subdomain (1.ex.example.com and 2.ex.example.com) they can share the same cookie. Because cookie is based on the domain itself.

is it possible to intercept the response to an HTTP OPTIONS preflight in AngularJS?

I'm trying to implement a simple interceptor that allows me to display a message along the lines of "cannot contact the server" in my Angular app. However as the API is on a different host I'm dealing with CORS pre-flight OPTIONS requests.
I've found that if the API is unavailable Chrome dev tools shows a 503 on the OPTIONS request but Angular's $http interceptor catches a 404 response to the subsequent GET request. I believe this is because the OPTIONS response did not contain the required CORS headers so the GET is actually never performed.
Is is possible to intercept the OPTIONS response? If all I see is a 404 I can't distinguish "server down" from "no such resource".
You can't intercept this request by design - the browser is "checking up" on you, making sure YOU should be allowed to make the request.
We've used three solutions to work around this:
If the problem is that you're using a development environment like NodeJS, and your domain names aren't matching (that is, if you normally wouldn't need to deal with this in Production) you can use a proxy. The https://github.com/substack/bouncyBounceJS NodeJS Module is an easy to use option. Then your Web service request domain will match the domain your page is on, and the check won't be triggered. (You can also use tricks like this in Production, although it can be easily abused!)
Also for temporary use, you can use something like Fiddler or Charles to manipulate the request by faking the required headers, or tell your browser not to check them (--disable-web-security in Chrome).
If you have this problem in Production, you either need to legitimately fix it (adjust the Web service handler to add the required headers - there are only two), or find a way to make the request in a way that doesn't trigger the check. For instance, if you control both the source and target domains, you can put a script on the target that makes the requests to itself. Run this in an IFRAME, invisibly. Then you can use things like postMessage() to communicate back and forth. Large services like Facebook use "XHR bridges" like this for the same reason.

Resources