“请求头字段Authorization不允许”错误 - Tastypie

35

使用ApiKeyAuthentication对我的Tastypie资源进行HTTP请求时,当我尝试使用AJAX和Tastypie执行HTTP请求时,出现以下错误:

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.

你有解决这个问题的任何想法吗?

以下是来自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

以下是来自 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

如您所见,它们都有“Authorization”标头,但授权无法正常工作。

这是我使用的Django中间件来编辑响应标头: https://gist.github.com/1164697

编辑:我找到问题了。我试图连接到www.domain.com,但它只接受domain.com。

5个回答

77
Antyrat的回答不完整。
您必须指定服务器允许的标头,例如您的情况下Authorization
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization

3
非常感谢。我想补充一点,我有点“懒”,曾尝试使用“Access-Control-Allow-Headers: *”,但它不起作用,但是使用“Authorization”确实有效。 - Yair Zaslavsky

2

虽然我赞同@Manuel Bitto的回答,
但是我想发布另一个包含完整Cors过滤器且适用于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);
    }
}

我建议特别关注向“Access-Control-Allow-Methods”头值添加OPTIONS。这样做的原因是,根据Mozilla在这里提供的解释,如果您的请求(比如POST)包含特殊头或内容类型(这也是我的情况),那么XMLHttpRequest对象将生成一个额外的OPTIONS调用,您需要在代码中处理它。希望这可以帮到您。

1
这是由于同源策略引起的。
您需要从与请求相同的域进行AJAX调用。或进行服务器端更改,允许来自外部域的请求。
为了解决此问题,您需要在http://domain.com的标头中进行更改,允许您的外部域名出现在标头中:
Access-Control-Allow-Origin: *

阅读更多


AJAX调用来自同一域。我该如何进行服务器端更改以允许来自外部域的请求,这样做存在哪些安全问题? - egidra
1
我在所有的ajax请求中添加了以下标头:'Access-Control-Allow-Origin': '*'。但我仍然收到相同的错误消息:请求标头字段Authorization不被Access-Control-Allow-Headers允许。 - egidra
你需要将此标头添加到响应(服务器端),而不是请求(客户端)。 - antyrat
嗯,我仍然有问题。我已经更新了我的原始消息,包括响应和请求头。 - egidra
1
被标记为正确答案的答案实际上是不正确的。@egidra,您能否接受Manuel Bitto或Antyrat的答案。现在非常令人困惑。 - botenvouwer

0

我知道这个问题比较老了。

但是今天在添加 owin 后,我遇到了同样的 cors 问题。在谷歌上进行了多次搜索并尝试了各种解决方案后,我通过添加以下内容解决了 cors 问题。

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

更多细节请点击以下链接。谢谢。

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


0
问题是www.domain.com被视为与domain.com不同。 domain.com可以使用,但当我使用www.domain.com时,它会将我识别为从不同的域发出请求。

4
您应该将antyrat的回答标记为正确答案。那个回答更详细,提供了链接,早些时候就已经写好,并且..您知道...是正确的。 - xyhhx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接