AJAX 访问代理提供的基本身份验证后的节点 API

Posted

技术标签:

【中文标题】AJAX 访问代理提供的基本身份验证后的节点 API【英文标题】:AJAX access to node API behind basic auth provided by proxy 【发布时间】:2018-11-27 22:33:24 【问题描述】:

我得到了一个用 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 放在基本身份验证之后,而不用改变 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?重复

我知道如何明确设置要获取的标头。我想要的是浏览器在应用程序落后于基本身份验证时隐式设置它们,而不需要对我的客户端代码进行任何修改。

【问题讨论】:

Basic authentication with fetch?的可能重复 请阅读developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch 了解credentials 选项的用法,它可能已经是您需要的了。 @Tomalak:谢谢!看起来答案是 RTFM。我必须在 fetch 的选项中指定credentials: 'include'。如果你写一个,我可以接受你的答案。 我不确定这是否包含基本的身份验证标头,所以我犹豫了。如果你写答案很好,我会投票,每个人都很高兴。 :) 【参考方案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) )

注意 fetch 选项中的 credentials: 'include'(可以使用 same-origin 代替 include 以获得更严格的安全性)。

这样,浏览器将在必要时隐式设置身份验证标头。

【讨论】:

您可以试试credentials: 'same-origin' 并确认这是否也有效吗? 从我读到的same-origininclude 之间的区别,我也这么认为。

以上是关于AJAX 访问代理提供的基本身份验证后的节点 API的主要内容,如果未能解决你的问题,请参考以下文章

MVC 身份验证超时/会话 cookie 删除后的 Ajax 请求

Ruby:摘要代理身份验证

经过身份验证的服务不支持跨域 javascript 回调。通过 SSL 代理对 WCF 服务的 AJAX 查询

节点 NPM 代理身份验证 - 我如何配置它?

HTTPS URL 的基本代理身份验证返回 HTTP/1.0 407 需要代理身份验证

(407) 需要代理身份验证 - 基本身份验证