【问题标题】:Node, express API proxy requests to external API with basic auth header节点,使用基本身份验证标头向外部 API 表达 API 代理请求
【发布时间】:2013-11-13 15:50:13
【问题描述】:

我已经使用 node.js 和 express 构建了一个 API。 但我需要能够将特定路由上的一些请求代理到外部服务器,并将外部服务器的响应显示给执行请求的 clint。

但我还需要转发客户端与请求一起发送的基本身份验证。

我尝试过使用请求模块,例如:

app.get('/c/users/', function(req,res) {
  //modify the url in any way you want
  var newurl = 'https://www.external.com' 
  request(newurl).pipe(res),

})

但它似乎没有发送基本的身份验证标头,因为我从外部服务器(www.external.com)得到“403 Forbidden”

我提出的请求是这样的:

GET http://example.se:4000/c/users/ HTTP/1.1
Accept-Encoding: gzip,deflate
X-version: 1
Authorization: Basic bmR4ZHpzNWZweWFpdjdxfG1vcmV1c2*******=
Accept: application/json
Host: example.se:4000
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

如果我执行完全相同的请求但直接针对 www.external.com,它会起作用,因此在节点中执行代理时会出现一些问题。

【问题讨论】:

    标签: node.js api express proxy


    【解决方案1】:

    request 模块完全不知道您没有明确传递给它的任何内容。要设置请求标头并复制响应标头,请执行以下操作:

    // copy headers, except host header
    var headers = {}
    for (var key in req.headers) {
      if (req.headers.hasOwnProperty(key)) {
        headers[key] = req.get(key)
      }
    }
    headers['host'] = 'final-host'
    
    var newurl = 'http://final-host/...'
    request.get({url:newurl, headers: headers }, function (error, response, body) {
      // debug response headers
      console.log(response.headers)
      // debug response body
      console.log(body)
    
      // copy response headers
      for (var key in response.headers) {
        if (response.headers.hasOwnProperty(key)) {
          res.setHeader(key, response.headers[key])
        }
      }
      res.send(response.statusCode, body)
    })
    

    【讨论】:

    • 好吧,据我了解,我应该将 request(newurl).pipe(res) 替换为: .get({url:newurl, headers{'Authorization': req.get('Authorization') }}).pipe(res);但我比得到:request.get({url:newurl, headers{'Authorization': req.get('Authorization') } ^ SyntaxError: Unexpected token {
    • Aaa 应该已经看到了。嗯,因为我得到 403 Forbidden,所以仍然无法工作。我可以得到发送的日志吗?当我返回 console.log(res);我得到了很多我不明白的东西。
    • 如果您想查看输出而不是管道结果,您可以在第一个方法调用的末尾放置一个回调:request.get({...}, function (error, response, body) { console.log(body); res.send(response.statusCode, body) }。参见request模块的文档。
    • 是否可以在不手动设置的情况下转发所有标头,例如 request.get({url:newurl, headers: req.headers}).pipe(res);但不是覆盖主机头?因为如果我从请求中传递主机头,我会得到一个错误。
    • 能否请您给stackoverflow.com/questions/22684644/…一些建议,我将不胜感激:)
    【解决方案2】:

    尝试像这样显式传递身份验证详细信息

    request(newurl).auth(username, password).pipe(res);
    

    https://github.com/mikeal/request#http-authentication

    【讨论】:

    • 但我只从客户端请求中获取编码在标头中的身份验证代码,例如:授权:基本 bmR4ZHpzNWZweWFpdjdxfG1vcmV1c2*******= 所以我不能只添加用户名/密码。我需要以某种方式转发此标头。
    • 您可以像这样设置标头 `request({ url: newurl, headers: {'Authorization': 'Basic bmR4ZHpzNWZweWFpdjdxfG1vcmV1c2*******='}}).pipe(res) ;`
    • 对不起,我现在没有关注你,我没有那么有经验的 witd node 和 express。我想我需要从请求中获取标头并将其传递给外部服务器的传出请求?
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2012-10-02
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2020-08-25
    • 2014-12-11
    相关资源
    最近更新 更多