通过添加从另一个请求返回的身份验证令牌来修改 http 代理请求

Posted

技术标签:

【中文标题】通过添加从另一个请求返回的身份验证令牌来修改 http 代理请求【英文标题】:Modify http proxy request by adding auth token returned from another request 【发布时间】:2019-12-07 19:28:36 【问题描述】:

我正在使用 http-proxy-middleware (https://github.com/chimurai/http-proxy-middleware#http-proxy-events) 实现一个简单的代理(称为 my-proxy/)到另一个 REST API(称为 /rest-api),它需要用户传递一个身份验证令牌在 HTTP 标头 auth-token 中。可以使用正文中的凭据从端点 POST /rest-api/auth 获取令牌。

我希望我的代理接收传入请求并检查是否在请求标头中设置了auth-token,如果没有,则执行POST /rest-api/auth 以检索令牌并在将请求传递给之前在标头中设置auth-token rest-api/.

在我指定的代理配置中

onProxyReq: function (proxyReq, req, res) 
        if (!req.header("auth-token")) 
            const authRequest = request(
                    url: 'rest-api/auth',
                    method: 'POST',
                    json: "username": "user", "password": "pass"
                ,
                function (error, resp, body) 
                    proxyReq.setHeader("auth-token", body.token)
                
            );
        
    

我可以看到 body.token 返回正确的令牌。然而,setHeader 调用失败并显示Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

我认为这意味着我修改的请求在等待回调之前已经发送到rest-api/,但我不知道在我的场景中如何最好地解决这个问题。

有什么帮助吗?

【问题讨论】:

【参考方案1】:

我今天遇到了同样的问题。我通过使用单独的中间件(在 http 代理之前)来解决这个问题。

伪代码

// fix token stuff here in a separate middleware
app.use('/api', async (req, res, next) => 

    if (!req.session.token) 
       const resToken = await axios.post(token_url, data, options)
       req.session.token = resToken.data
    
    next()


// proxy middleware options
const proxyOptions = 
  target: config.gateway.url, // target host
  changeOrigin: true,
  pathRewrite: function(path, req) 
    return path.replace('/api', '')
  ,
  onProxyReq: function onProxyReq(proxyReq, req, res) 
    // add custom header to request
    let token = req.session.token
    if (token) 
      proxyReq.setHeader('Authorization', `bearer $token.access_token`)
    
  ,
  logLevel: 'debug',


app.use(proxy('/api', proxyOptions))

希望这会有所帮助!

【讨论】:

忘记发布我的解决方案,但我最终还是做了同样的事情,只是我在中间件内部调用了代理,所以我只注册了那个中间件,我认为这是更好的封装。

以上是关于通过添加从另一个请求返回的身份验证令牌来修改 http 代理请求的主要内容,如果未能解决你的问题,请参考以下文章

Spring过滤器将角色添加到来自令牌的请求

在 ember-file-upload 的请求标头中添加身份验证令牌

忽略某些路由上的过期令牌

根据 JWT 身份验证令牌中的声明验证来自请求的 IP

Azure 身份验证受众验证失败

如何在http请求角度添加令牌