Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restify and Angular CORS No 'Access-Control-Allow-Origin' header is present on the requested resource

I faced with that problem when implementing REST api with Restify secured with bearer token authorization type.

when I sending simple get request to API server it fails with CORS problem

405 (Method Not Allowed) angular.js:7962

OPTIONS http://api.host.com/tests No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://local.host.com' is therefore not allowed access.


Solution described in my answer, so it's not real question for me, because I placed it when already know the answer, but hope it will save time for someone else in future.

like image 928
Ph0en1x Avatar asked Jan 06 '14 20:01

Ph0en1x


2 Answers

The problem was faced because of restify has internal CORS module who manage CORS logic. in this module you could find list of allowed headers, by default it's

[
        'accept',
        'accept-version',
        'content-type',
        'request-id',
        'origin',
        'x-api-version',
        'x-request-id'
]

As I say in the question, I use bearer token auth, so I send my request with Authorization header. It's not included in default list, and that's why my request fails.

To fix that problem we need to add this header to the list of ALLOW_HEADERS. for that in my restify configuration code I add this line:

restify.CORS.ALLOW_HEADERS.push('authorization');

Think that info could be helpfull if you faced with similar problem, because I spend a lot to find the solution.

like image 56
Ph0en1x Avatar answered Oct 21 '22 10:10

Ph0en1x


You won't be able to access the URL http://api.host.com/tests from a file deployed at http://local.host.com due to the same-origin policy.


As the source (origin) page and the target URL are at different domains, your code is actually attempting to make a Cross-domain (CORS) request (thus the error with OPTIONS -- see the explanation below), not an ordinary GET.

In a few words, the same-origin policy enforces that browsers only allow Ajax calls to services in the same domain as the HTML page.


Example: A page in http://www.example.com/myPage.html can only directly request services that are in http://www.example.com, like http://www.example.com/testservice/etc. If the service is in other domain, the browser won't make the direct call (as you'd expect). Instead, it will try to make a CORS request.

To put it shortly, to perform a CORS request, your browser:

  • Will first send an OPTION request to the target URL
  • And then only if the server response to that OPTIONS contains the adequate headers (Access-Control-Allow-Origin is one of them) to allow the CORS request, the browse will perform the call (almost exactly the way it would if the HTML page was at the same domain).

If the expected headers don't come in the OPTIONS, the browser will give up, informing the error (that it attempted a CORS request and didn't find the necessary headers).

How to solve it?

  • Place the target service in the same domain of the origin page; or
  • Enable CORS (enable the necessary headers) on the server; or
  • If you don't have server-side access to the service, you could also mirror it (create a copy of it in the server you own).
  • JSONP is also a solution if you just want to request information (but this would require server-side access to setup as well).
like image 45
acdcjunior Avatar answered Oct 21 '22 10:10

acdcjunior