javascript - 如何在预检请求中强制进行身份验证?
问题描述
我正在尝试从客户端 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);
控制台错误消息:
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 未找到
注意:当我尝试获取主分支时它工作正常(无论是否经过身份验证)。但是,它在被重定向后失败:
访问 '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 中的错误吗?或者我做错了什么?
解决方案
无法在预检请求中强制进行身份验证。预检完全由浏览器控制,不会以任何您可以从前端 JavaScript 代码操作的方式公开。CORS 协议的要求明确禁止浏览器在预检请求中包含任何凭据。有关详细说明,请参阅https://stackoverflow.com/a/45406085/上的答案。
由于预检涉及浏览器发出OPTIONS
请求,那么一般来说,如果服务器需要对OPTIONS
特定端点或资源的请求进行身份验证(问题中引用的 GitHub URL 似乎就是这种情况),这根本不一定是意外漏洞。
这是因为执行预检并发送OPTIONS
请求的唯一正常情况是前端 JavaScript 代码在浏览器中运行的情况。从服务器端代码或在 shell/命令行环境中运行的代码或从桌面应用程序或本机移动应用程序发出的请求不涉及发送OPTIONS
请求。
OPTIONS
因此,如果提供者实际上打算从在浏览器中运行的前端 JavaScript 代码中使用对特定端点/资源的未经身份验证的请求,那么缺乏对未经身份验证的请求的支持只会是一个错误。换句话说,它可以相反地表明提供者非常有意地并不意味着要从前端 JavaScript 代码中使用它(问题中引用的 GitHub URL 似乎就是这种情况)。
推荐阅读
- r - 如何模拟一个向量只包含 0、1、2 和给定的向量总和
- onem2m - 充电信息记录
- mysql - 错误 1452 MySQL Load Infile(但数据正确)
- sql - PostgreSQL 在查询返回空的情况下将 NULL 作为一行返回
- python - 根据行和列对矩阵中的所有元素进行排名
- spring-boot - WebFlux 如何以功能性非阻塞方式链接查询
- c# - 我怎样才能实现相同的物理学?
- javascript - Promise.all 结果符合预期,但个别项目显示未定义
- docker - Docker 容器没有正确使用 CPU
- javascript - 无法使用角度设置在列表组中单击按钮时选择的单选按钮值