代理

时间:2018-06-19 03:42:27

标签: node.js ajax http nginx

我得到了一个用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。我想要的是浏览器在应用程序落后于基本身份验证时隐式设置它们,而不对我的客户端代码进行任何修改。

1 个答案:

答案 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标头。