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

标签 javascript cors github-api client-side preflight

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

我的代码执行以下操作(我正在尝试获取包含私有(private)存储库的分支 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);

但是它不起作用: enter image description here 预检请求失败并返回 404。

控制台错误消息:

Access to fetch at 'https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.


在调试过程中,我尝试使用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 No Content

但是如果请求未经身份验证,则不起作用:

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

HTTP/1.1 404 Not Found


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

Access to fetch at 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX' (redirected from 'https://api.github.com/repos/astariul/private-gh-pages/zipball') from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.


这是 Github API 中的错误吗?或者我做错了什么?

最佳答案

无法在预检请求中强制进行身份验证。预检完全由浏览器控制,并且不会以任何可以从前端 JavaScript 代码操作的方式公开任何内容。 CORS 协议(protocol)的要求明确禁止浏览器在预检请求中包含任何凭据。

详细解释参见 https://stackoverflow.com/a/45406085/ 的答案.

由于预检涉及浏览器发出 OPTIONS 请求,因此一般来说,如果服务器需要对特定资源的 OPTIONS 请求进行身份验证(这似乎是问题中引用的 GitHub URL 的情况)这根本不一定是意外错误。

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

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

关于javascript - 如何在预检请求中强制进行身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68143581/

相关文章:

javascript - 使用另一个日期字段设置日期字段

javascript - 有没有办法在 C3.js 刻度标签中放置链接?

ajax - 在 WCF 服务上来自 AJAX 的 REST 请求期间在 CORS 中启用 OPTIONS 方法

jquery - URL 包含嵌入凭据的子资源请求被阻止的解决方案

node.js - 使用 nginx 代理在 node.js 应用程序上启用 Cors

github-api - Python GitHub "Status Check"POST 未找到错误! (404)

javascript - Github API 列出来源存储库

javascript - Web 浏览器中 xml 的树状 View

python - 通过 API 下载 Github 版本

javascript - 从选择输入中显示和隐藏多个输入框