I'm using the http-proxy-middleware (https://github.com/chimurai/http-proxy-middleware#http-proxy-events) to implement a simple proxy (call it my-proxy/
) to another REST API (call it /rest-api
) that requires the user to pass an auth token in the HTTP header auth-token
. The token can be fetched from an endpoint POST /rest-api/auth
with the credentials in the body.
I want my proxy to take incoming requests and check if auth-token
is set in the the request header, and if not perform a POST /rest-api/auth
to retrieve the token and set auth-token
in the header before passing the request to rest-api/
.
In the proxy config I specify
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)
}
);
}
}
I can see the body.token
return the right token. However the setHeader
call fails with Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
.
I think this means the request I modify has already been sent to rest-api/
before waiting for the callback, but I don't know how this is best solved in my scenario.
Any help?
I met this same issue today. I workaround this by using a separate middleware (before http proxy).
pseudo code
// 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))
Hope this helps!