node.js - AJAX 访问代理提供的基本身份验证后的节点 API
问题描述
我得到了一个用 node.js 编写的普通 API,例如:
const express = require('express')
const app = express();
app.post('/api/data', (req, res) => {
res.status(200).json({
data: [1,2,3,3,1,3,5,2,3,4,4,7]
})
})
app.use('/gui', express.static('./gui'))
app.listen(8080, () => { console.log("OK") })
和一个客户端javascript代码使用该fetch
函数访问它,这种方式(例如./gui/index.html
):
fetch('/api/data', {
method: 'post',
headers: {
'Accept': 'application/json', 'Content-Type': 'application/json'
},
body: JSON.stringify(json)
})
.then( res => { console.log(res })
它工作得很好,但现在我想把这个 API 放在基本身份验证后面,而不用改变 API 代码,使用 nginx 作为中间人。配置文件如下所示:
server {
listen 80;
location / {
auth_basic "Private Area";
auth_basic_user_file .htpasswd;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
现在,当我在浏览器中打开页面时,它会询问身份验证信息,显示 HTML,但 AJAX 访问失败并出现 401 错误。
检查后,浏览器似乎没有为 AJAX 访问发送授权标头。
问题是:有没有办法使基本身份验证对我的 API 和 GUI 透明?我做错了什么?
编辑
有人建议这个问题是Basic authentication with fetch 的副本?
我知道如何明确设置要获取的标题。我想要的是浏览器在应用程序落后于基本身份验证时隐式设置它们,而不需要对我的客户端代码进行任何修改。
解决方案
正如@Tomalak 所建议的那样,并根据https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
默认情况下,fetch 不会从服务器发送或接收任何 cookie,如果站点依赖于维护用户会话(要发送 cookie,必须设置凭据 init 选项),则会导致未经身份验证的请求。
换句话说,我所要做的就是修改我的调用以获取这种方式:
fetch('/api/data', {
credentials: 'include',
method: 'post',
headers: {
'Accept': 'application/json', 'Content-Type': 'application/json'
},
body: JSON.stringify(json)
})
.then( res => { console.log(res) })
请注意credentials: 'include'
in fetch 选项(可以使用same-origin
而不是include
更严格的安全性)。
这样,浏览器将在必要时隐式设置 auth 标头。
推荐阅读
- angular - 如何将重播主题数组存储在角度的单个变量中?
- perl - 参数不是按位或 (|) 的数字。为什么?
- applescript - Applescript 用户交互
- pickle - 使用新的 xgboost 版本“XGBClassifier”对象打开旧的 xgboost 泡菜没有属性“kwargs”
- flutter - Codemagic 后克隆脚本因找不到 base64 命令而失败
- linux - Gunicorn 不会拒绝超过积压限制的连接
- performance - Julia 中更快的向量比较
- django - 如何使用表单获取对象,然后使用 url 将其发送到下一个视图?
- python - Metropolis monte carlo 理想气体模拟量归零
- asp.net-mvc - 使用 Asp.net mvc 创建用户和角色