如何在预检请求中强制进行身份验证?

Posted

技术标签:

【中文标题】如何在预检请求中强制进行身份验证?【英文标题】:How to force authentication in preflight request? 【发布时间】:2021-09-09 14:11:11 【问题描述】:

我正在尝试从客户端 javascript(在浏览器中)调用 Github REST API。

我的代码执行以下操作(我正在尝试获取包含私有存储库的分支 mkdocs_page 的 zip):

    const endpoint = 'https://api.github.com';
    const resource = '/repos/astariul/private-gh-pages/zipball/mkdocs_page';
    const options = 
      mode: 'cors',
      headers: 
        'Authorization': 'Basic ' + btoa(`$pat`),  // pat contains my Personal Access Token
      
    

    return fetch(`$endpoint$resource`, options);

但它不起作用: 预检请求失败并返回 404。

控制台错误信息:

CORS 政策已阻止访问“https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page”从源“null”获取:对预检请求的响应不” t 通过访问控制检查:它没有 HTTP ok 状态。


在调试这个的过程中,我尝试用curl重现问题。当我指定一个经过身份验证的请求时,它可以工作:

curl --user "<my_PAT_token>" -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS

HTTP/1.1 204 无内容

但是如果请求没有经过身份验证,它就不起作用:

curl -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS

HTTP/1.1 404 未找到


注意:当我尝试获取主分支时它工作正常(无论是否经过身份验证)。但是,在被重定向后它会失败:

访问 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX'(重定向自 'https://api. github.com/repos/astariul/private-gh-pages/zipball') 来自原点'null' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin ' 请求的资源上存在标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。


这是 Github API 的错误吗?还是我做错了什么?

【问题讨论】:

【参考方案1】:

无法在预检请求中强制进行身份验证。预检完全由浏览器控制,不会以任何您可以从前端 JavaScript 代码操作的方式公开。 CORS 协议的要求明确禁止浏览器在预检请求中包含任何凭据。详细解释见https://***.com/a/45406085/的答案。

由于预检涉及到浏览器发出 OPTIONS 请求,那么一般来说,如果服务器需要对特定端点或资源的 OPTIONS 请求进行身份验证(这似乎是问题)这根本不一定是一个意外的错误。

这是因为执行预检并发送OPTIONS 请求的唯一正常情况是前端 JavaScript 代码在浏览器中运行的情况。从服务器端代码或在 shell/命令行环境中运行的代码或从桌面应用程序或本机移动应用程序发出的请求不涉及发送 OPTIONS 请求。

因此,如果提供者实际上打算从在浏览器中运行的前端 JavaScript 代码中使用未经身份验证的 OPTIONS 请求,那么缺乏对特定端点/资源的请求的支持只会是一个错误。换句话说,它可以相反地表明提供者非常有意地并不意味着要从前端 JavaScript 代码中使用它(问题中引用的 GitHub URL 似乎就是这种情况)。

【讨论】:

以上是关于如何在预检请求中强制进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 2 中使用基本身份验证预检 CORS 请求

为啥经过身份验证的 CORS 请求的预检 OPTIONS 请求在 Chrome 中有效,但在 Firefox 中无效?

PouchDB 身份验证触发 CORS 预检请求

预检请求没问题,然后,经过身份验证,响应不包含允许 cors 标头

对 C# 中的每个请求强制进行 Azure 重新身份验证

使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求