Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Request succeeds on server but results in CORS error in browser

I do an HTTP POST request to the microsoft login to get an access token to use with the mail API, the request succeeds but the code goes to the error clause of my code.

requestAccessToken(code: string)
{
console.log("request access token");
if (code) {
  var headers = new Headers();
  headers.append("Content-Type", 'application/x-www-form-urlencoded');
  headers.append('Accept', 'application/json');
  var requestoptions = new RequestOptions({
    headers: headers
  });
  var body = `grant_type=authorization_code&
              redirect_uri=http://localhost:4200&
              code=`+ code + `&
              client_id=4e[................]5ab&
              client_secret=CE[..............]BC`;

  this.http.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", body, requestoptions).map((res: Response) =>
  {
    console.log("response given");
    const data = res.json();
  }).subscribe( (data) => {
     console.log("The data is = " + data); 
  }, error => { 
    console.log("The error is = " + error)
  });
}

The browser console shows this: XMLHttpRequest cannot load https://login.microsoftonline.com/common/oauth2/v2.0/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. zone.js:2019 XHR failed loading: POST "https://login.microsoftonline.com/common/oauth2/v2.0/token". outlook.service.ts:96 The error is = Response with status: 0 for URL: null

here's a screenshot to show it better Console error log

Now the real problem is that my request succeeds as shown below: Browsers' network tab

and the response shows my access token. So why cannot I get it from code? Why does it go the error-clause.

like image 338
Wouter Vandenputte Avatar asked May 26 '17 08:05

Wouter Vandenputte


People also ask

How do I fix a CORS error in my browser?

To get rid of a CORS error, you can download a browser extension like CORS Unblock. The extension appends Access-Control-Allow-Origin: * to every HTTP response when it is enabled. It can also add custom Access-Control-Allow-Origin and Access-Control-Allow-Methods headers to the responses.

Is CORS blocked by browser or server?

Cross-Origin Resource Sharing (CORS) is a mechanism or a protocol that allows devices on one domain to access resources residing on other domains. Generally, for security reasons, browsers forbid requests that come in from cross-domain sources.

How do I fix the CORS problem on Chrome?

You can customize what methods are allowed. The default option is to allow "WEBDAV", "GET", "PUT", "POST", "DELETE", "HEAD", "OPTIONS", "PATCH" methods. You can also ask the extension not to overwrite these headers when the server already fills them. This extension also fixes CORS policies of redirected URLs.

How do I bypass browser CORS?

CORS-escape provides a proxy that passes on our request along with its headers, and it also spoofs the Origin header (Origin = requested domain). So the CORS policy is bypassed. The source code is on Github, so you can host your own. Proxying is kinda like “passing on" your request, exactly as you sent it.


2 Answers

You already tagged your post correctly with "cors". Modern browsers does not allow accessing endpoints across domains, unless the endpoint sends cors-headers which allows you to access it.

If you check your network tab, there should be an OPTIONS-request to https://login.microsoftonline.com/common/oauth2/v2.0/token. This s called he preflight-request, which checks for Access-Control-Allow-Origin and Access-Control-Allow-Methods headers. Access-Control-Allow-Origin must contain your domain or *, and Control-Allow-Methods must contain POST or *.

I'm not familiar with the office apis, but i think there must be a way to configure your app as an valid endpoint. Perhaps this post will help you: https://msdn.microsoft.com/en-us/office/office365/howto/create-web-apps-using-cors-to-access-files-in-office-365

like image 83
Markus Kollers Avatar answered Oct 16 '22 19:10

Markus Kollers


What you’re seeing is expected behavior when sending a cross-origin request to a server but not receiving the Access-Control-Allow-Origin response header in the response.

Specifically, as long as your cross-origin request has no characteristics that cause your browser to do a preflight OPTIONS request before making your request, then the request will succeed on the server side — but, because the response from the server to that request doesn’t include the Access-Control-Allow-Origin response header, your browser blocks your frontend code from being able to actually see the response the server sends.

However, if you open browser devtools you can still see the response there. But just because the browser received the response and you can see it in devtools, it doesn’t mean the browser will expose the response to your code. It’ll only expose it when it has Access-Control-Allow-Origin.


That all may seem counter-intuitive but it all makes sense if you remember that the browser is the only point at which cross-origin restrictions are enforced. Servers don’t block cross-origin requests.

When the server you’re sending that request to receives the request, it doesn’t check the origin to decide whether to respond. The server just accepts the request and processes it and then sends a response. But then the browser blocks your code from access to that response.

But it’s also important to remember that the browser doesn’t block your code from sending that request cross-origin. Browsers only block cross-origin requests from being sent when the requests have qualities (like special headers) that trigger the browser to do a preflight.

So if your request isn’t one that triggers a preflight, the browser sends it and the server receives it and processes it. And if the request method is POST or some other whose purpose is to change state on the server — in which case you may not care much what the response is — then to the degree that the request had the intended effect on the server side, it can be considered successful.

But consider what happens when you do actually care a lot what the response is: Consider what happens for GET requests, where the entire point of making the request is to get back a response.

As explained above, if the request isn’t one that triggers a preflight, the browser sends it, the server receives it, and returns a response. But if the response doesn’t include the Access-Control-Allow-Origin response header, your browser won’t let your frontend JavaScript code access it.

Obviously since the entire point of making a GET request is to do something with the response, then in that case if your code can’t access the response, that’s a hard, total failure — in contrast to the case of the POST request, where the request body does actually still get posted as expected, but you just don’t have a way for your code to check the response to see if the request succeeded.

like image 42
sideshowbarker Avatar answered Oct 16 '22 18:10

sideshowbarker