由于CORS,浏览器中的HTTP身份验证请求失败,节点中正常 [英] HTTP Auth request fails in browser due to CORS, ok in Node

查看:185
本文介绍了由于CORS,浏览器中的HTTP身份验证请求失败,节点中正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试诊断问题,其中使用HTTP Basic Auth的GET请求在Node中成功,但是在浏览器中失败.该问题直接表现为CORS故障(401页上没有Access-Control-Allow-Origin).

I'm stuck trying to diagnose a problem where a GET request with HTTP Basic Auth succeeds in Node, but fails in the browser. The problem manifests directly as a CORS failure (there's no Access-Control-Allow-Origin on the 401 page).

request.js:119 OPTIONS http://HOST?PARAMS 401 (Unauthorized)
ClientRequest._onFinish @ request.js:119
(anonymous) @ request.js:61
...

17:53:59.170 localhost/:1 Failed to load http://HOST?PARAMS: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9966' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

请求看起来像这样:

const request = require("request-promise");
const options = {"url":"http://...?","auth":{"user":"...","pass":"..."},"json":true,"qs":{...},"headers":{},"resolveWithFullResponse":true}
request.get(options).then(...);

此请求如何在Chrome中显示:

How this request shows up in Chrome:

这让我感到惊讶:

  • 方法是OPTIONS,而不是GET.(我没有明确要求.)
  • 我的身份验证凭据不包含在标题中(即使我没有立即设置 send:false
  • 已显示临时标题"警告.

我想知道的事情:

  • 这是预期的行为吗?
  • 如果没有,怎么了?
  • 如果是,怎么了?:)

在命令行上运行等效请求似乎正常:

Running what would be the equivalent request on the command line seems to work fine:

curl -I 'http://MYUSERNAME:MYPASSWORD@SAMEURL?SAME=PARAMETERS' -H 'Origin: http://localhost:4466' -X OPTIONS
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2018 07:29:28 GMT
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:4466
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Vary: Origin
X-Frame-Options: SAMEORIGIN
Allow: GET,HEAD,POST,OPTIONS
Content-Length: 0

但是我注意到没有URL中提供的凭据,响应中没有CORS标头:

However I notice that without the credentials supplied in the URL, there are no CORS headers on the response:

HTTP/1.1 401 Unauthorized
Date: Wed, 20 Jun 2018 07:45:26 GMT
Server: Apache/2.4.29 (Unix) OpenSSL/1.0.2l
WWW-Authenticate: Basic realm="Authentication Required"
Content-Length: 381
Content-Type: text/html; charset=iso-8859-1

这是正确的行为吗?

我怀疑:

  • 浏览器正在发送OPTIONS飞行前"请求,因为它不是简单请求",因为它必须发送.(这不是完全是请求库还是浏览器本身在做)
  • 服务器未响应401,因为未提供凭据,但未添加应有的CORS标头.
  • 没有CORS标头,浏览器将阻止请求库访问结果,因此无法完成身份验证.

我不确定的是什么

  • 服务器配置错误吗?
  • 请求是否无法在OPTIONS飞行前请求中传递凭据?

推荐答案

服务器配置错误.没有正确启用CORS.要正确启用CORS,它必须使用状态码为 200 或状态码为 204 的未经身份验证的 OPTIONS 请求进行响应.

The server is misconfigured. It’s not properly CORS-enabled. To be properly CORS-enabled it must respond to unauthenticated OPTIONS requests with a 200 or 204 status code.

Request 并非未能"通过 OPTIONS 预检请求中的凭据. Request 甚至没有发出 OPTIONS 请求.取而代之的是浏览器引擎.

Request isn’t "failing" to pass credentials in the OPTIONS preflight request. Request isn’t even making the the OPTIONS request. Instead the browser engine is, on its own.

并且在您自己的代码中为请求指定凭据标志不会导致凭据被添加到预检 OPTIONS 请求中.取而代之的是,凭据只能从您自己的代码添加到 GET 请求中-也就是说,如果预检成功并且浏览器实际上一直在进行该 GET 请求.

And specifying the credentials flag for the request in your own code doesn’t cause credentials to get added to the preflight OPTIONS request. Instead, credentials only get added to the GET request from your own code — that is, if the preflight has succeeded and the browser actually ever moves on to making that GET request.

这是因为Fetch中的CORS协议要求指定浏览器必须忽略飞行前 OPTIONS 请求中的所有凭据.

That’s because the CORS-protocol requirements in the Fetch specify that browsers must omit all credentials from preflight OPTIONS requests.

请参见 https://fetch.spec.whatwg.org/#ref-for-credentials%E2%91%A5 :

CORS预检请求从不包含凭据

a CORS-preflight request never includes credentials

因此,您遇到的行为是有意设计的.

So the behavior you’ve encountered is intentional, by design.

有关详细说明,请参见

For a related explanation in more detail, see the answer at HTTP status code 401 even though I’m sending an Authorization request header.

这篇关于由于CORS,浏览器中的HTTP身份验证请求失败,节点中正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆