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

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

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

    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策略已阻止从源‘Null’获取‘https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page’的访问:对印前检查请求的响应未通过访问控制检查:它没有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


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

CORS策略阻止了对在‘https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX’处提取的访问(从源‘NULL’从‘https://api.github.com/repos/astariul/private-gh-pages/zipball’)重定向):对印前检查请求的响应未通过访问控制检查:请求的资源上不存在‘Access-Control-Allow-Origin’标头。如果不透明的响应满足您的需求,请将请求的模式设置为‘no-CORS’,以在禁用CORS的情况下获取资源。


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


解决方案

无法在印前检查请求中强制身份验证。印前检查完全由浏览器控制,任何有关它的内容都不会以任何您可以从前端JavaScript代码操作的方式公开。CORS协议的要求明确禁止浏览器在印前检查请求中包含任何凭据。有关详细说明,请参阅https://stackoverflow.com/a/45406085/中的答案。

由于印前检查涉及浏览器发出OPTIONS请求,因此,通常情况下,如果服务器要求对特定终结点或资源的OPTIONS请求进行身份验证(问题中引用的GitHub URL似乎就是这种情况),则根本不一定是意外错误。

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

因此,如果提供者实际上打算从浏览器中运行的前端JavaScript代码使用对特定终结点/资源的未经身份验证的OPTIONS请求,则缺乏对该请求的支持才是错误。换句话说,它可以非常故意地指示提供者并不意味着它将从前端Java代码中使用(这似乎就是问题中引用的GitHub URL的情况)。

相关文章