我得到了一个用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") })
以及使用fetch
函数以这种方式访问它的客户端JavaScript代码(例如./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放在基本身份验证之后,而不是使用nginx作为man在中间更改API代码。配置文件如下所示:
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;
}
}
现在,当我在浏览器中打开页面时,它会询问auth信息,显示HTML,但是AJAX访问因401错误而失败。
检查后,浏览器似乎没有发送AJAX访问的授权标头。
问题是:有没有办法让基本身份验证对我的API和GUI透明?我做错了什么?
修改
有人建议此问题与Basic authentication with fetch?
重复我知道如何将标头明确设置为fetch。我想要的是浏览器在应用程序落后于基本身份验证时隐式设置它们,而不对我的客户端代码进行任何修改。
答案 0 :(得分:1)
正如@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'
(可以使用same-origin
代替include
来提高安全性。)
这样,浏览器会在必要时隐式设置auth标头。