简体   繁体   English

如何使用授权标头进行GET CORS请求

[英]How to make GET CORS request with authorization header

I was reading about CORS requests, and I have managed to make regular GET or POST request and it works fine. 我正在阅读有关CORS请求的信息,并且我设法发出了常规的GET或POST请求,并且工作正常。 But when I add authorization header to a either GET or POST request, then the preflight OPTIONS request is sent to the server and I get 500 INTERNAL SERVER ERR, and the actual request isn't sent. 但是,当我将授权标头添加到GET或POST请求中时,则将预检OPTIONS请求发送到服务器,并且我得到500 INTERNAL SERVER ERR,并且未发送实际请求。 My question is how does the preflight actually work, and what response does it require so that it will send the main request? 我的问题是,预检实际上是如何工作的,需要什么响应才能发送主要请求? And is it possible to send it without the preflight because I'm sure that then it would work? 是否可以在不进行预检的情况下发送它,因为我确定这样就可以了? The serve-rside is written in Django 1.6 and has ACCESS-ALLOW-ORIGIN set to *, and it works with regular post and get requests. serve-rside用Django 1.6编写,并且ACCESS-ALLOW-ORIGIN设置为*,并且可以处理常规的post和get请求。

This is my JS code: 这是我的JS代码:

 $.ajax({
  type: "GET",
  url: "http://url/login/",
  async:false,
  contentType: "application/json",
  headers: {
    "Authorization": "Basic " + btoa(loginName + ':' + password),       
  },
  success: function (data) {
    alert("OK!");
  },
  failure: function(errMsg) {
    alert(errMsg);
  }
});

These are the headers from Chrome DevTools when the request is executed: Request headers: 这些是执行请求时来自Chrome DevTools的标头:请求标头:

OPTIONS /login/ HTTP/1.1
Host: url
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)     Chrome/36.0.1985.125 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6,sr;q=0.4

Response headers: 响应头:

HTTP/1.1 500 INTERNAL SERVER ERROR
Date: Thu, 31 Jul 2014 16:15:19 GMT
Server: Apache/2.2.15 (CentOS)
X-Frame-Options: SAMEORIGIN
Access-Control-Allow-Origin: *
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

To pass authorization headers you must set Access-Control-Allow-Credentials to true. 要传递授权标头,必须将Access-Control-Allow-Credentials为true。

The problem is that, according to specification ( MDN explains it simpler ), if Access-Control-Allow-Credentials is set to true, Access-Control-Allow-Origin cannot contain * , therefore allowing any hosts making requests with credentials attached. 问题是,根据规范( MDN对此进行了更简单的解释 ),如果将Access-Control-Allow-Credentials设置为true,则Access-Control-Allow-Origin不能包含* ,因此允许任何主机发出带有凭据的请求。

There are two options to solve this problem: 有两种方法可以解决此问题:

  • Set Access-Control-Allow-Origin to actual host making requests Access-Control-Allow-Origin为实际的主机发出请求
  • If there are more than one host: "canonical" way would be to have a whitelist of hosts in application itself, than check Origin header if it's on the list and adding Origin as Access-Control-Allow-Origin header value. 如果主机不止一个:“规范”方式是在应用程序本身中拥有一个主机白名单,而不是检查Origin标头是否在列表中,然后将Origin添加为Access-Control-Allow-Origin标头值。

With Django, check for Origin and adding a header can be made in Middleware, but that would make a decent question on it's own (and probably have been already asked) 使用Django,可以在中间件中检查Origin并添加标头,但这本身就可能引起一个不错的问题(可能已经有人问过)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM