30

I am getting the following error while using ApiKeyAuthentication for my Tastypie resources when I try to do an HTTP request using AJAX and Tastypie:

XMLHttpRequest cannot load http://domain.com/api/v1/item/?format=json&username=popo&api_key=b83d21e2f8bd4952a53d0ce12a2314c0ffa031b1. Request header field Authorization is not allowed by Access-Control-Allow-Headers.

Any ideas on how to solve this?

Here are the request headers from Chrome:

Request Headersview source

Accept:*/*
Accept-Charset:
ISO-8859-1,utf-8;q=0.7,*;q=0.3

Accept-Encoding:gzip,deflate,sdch

Accept-Language:en-US,en;q=0.8

Access-Control-Request-Headers:
origin, authorization, access-control-allow-origin, accept, access-control-allow-headers

Access-Control-Request-Method:
GET

Here are the response headers from Chrome:

Response Headersview source

Access-Control-Allow-Headers:
Origin,Content-Type,Accept,Authorization

Access-Control-Allow-Methods:
POST,GET,OPTIONS,PUT,DELETE

Access-Control-Allow-Origin:*

Connection:keep-alive

Content-Length:0
Content-Type:
text/html; charset=utf-8

Date:Fri, 11 May 2012 21:38:35 GMT

Server:nginx

As you can see, they both have headers for Authorization, yet authorization does not work.

Here is the django middleware that I am using to edit the response headers: https://gist.github.com/1164697

Edit: I figured out the problem. I was trying to connect to www.domain.com, and it only accepts domain.com

egidra
  • 6,619
  • 16
  • 55
  • 85

5 Answers5

70

Antyrat's answer is not complete.

You have to specify which headers your server allows; in your case Authorization.

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization
Manuel Bitto
  • 4,777
  • 6
  • 37
  • 45
  • 3
    Thank you very much. I would like to add that I was a bit "lazy" and have tried to use "Access-Control-Allow-Headers: *" , and it did not work, but with "Authorization" it did work. – Yair Zaslavsky Jul 06 '15 at 05:55
2

Although I upvoted the answer of @Manuel Bitto,
I would like to post another answer which contains a complete Cors Filter that works for me with Apache tomcat 5.x:

public class CorsFilter implements Filter {

    public CorsFilter() { }

    public void init(FilterConfig fConfig) throws ServletException { }

    public void destroy() { }

    public void doFilter(

            ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE");
        httpServletResponse.addHeader("Access-Control-Allow-Headers", "Authorization");

        chain.doFilter(request, response);
    }
}

I would suggest to specifically pay attention to the addition of OPTIONS to to the "Access-Control-Allow-Methods" header values.
The reason for doing that is that according to the explanation provided here by Mozilla,
if your request (let's say POST) contains a special header, or content type (and this is my case), then the XMLHttpRequest object will generate an additional OPTIONS call, which you need to address in your code.
I hope this helps.

Yair Zaslavsky
  • 3,987
  • 2
  • 17
  • 25
1

This happens because of Same origin policy.

You need to make AJAX call from same domain where request goes. Or make server-side changes, allowing requests from external domains.

To resolve this you need to make changes in headers at http://domain.com by allowing your external domain in headers:

Access-Control-Allow-Origin: *

Read more

antyrat
  • 26,266
  • 9
  • 69
  • 74
  • The AJAX calls are coming from the same domain. How would I make server side changes to allow requests from external domains, and what are the security issues present by doing this? – egidra May 11 '12 at 09:38
  • 1
    I added the following header to all of my ajax requests: 'Access-Control-Allow-Origin': '*'. I am still getting the same error: Request header field Authorization is not allowed by Access-Control-Allow-Headers. – egidra May 11 '12 at 21:22
  • You need to add this header to response ( server-side ) not to the request ( client-side ) – antyrat May 11 '12 at 21:58
  • Hmm, I am still having problems. I updated my original message with the response and request headers. – egidra May 13 '12 at 19:35
  • The answer marked as correct is simply not correct. @egidra could you accept the answer of Manuel Bitto or Antyrat could you update your answer. Now it's very confusing. – botenvouwer Feb 20 '20 at 08:35
0

The problem was that www.domain.com was seen as different than domain.com. domain.com worked, but when I used www.domain.com, it detected me as doing requests from a different domain

egidra
  • 6,619
  • 16
  • 55
  • 85
  • 3
    You should probably mark antyrat's answer as correct. It is more detailed, provides links, was written earlier, and is.. you know... correct. – Martin May 23 '14 at 19:52
0

I know this question is older.

But today I ran into same cors issue after adding owin. After number of search on google and trying various solutions. I solved cors issue by adding below

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />

For more details please follow the below links. Thanks.

[http://benfoster.io/blog/aspnet-webapi-cors]

C For Code
  • 51
  • 6