http-proxy-middleware icon indicating copy to clipboard operation
http-proxy-middleware copied to clipboard

Unable to access session inside onProxyReqWs

Open georgyfarniev opened this issue 5 years ago • 7 comments

Hello, I have issue: I want to use onProxyReqWs for authentication. I need to take my session data and send it to websocket server as a header. But my connect middlewares are not getting called before proxy in case of websocket connection. Here is example:


app.use((req, res, next) => {
  req.test = 123
})

app.use(proxy({
  changeOrigin: true,
   ws: true,
   target: 'http://localhost:7045',
    onProxyReq(proxyReq, req, res) {
        // Everything is correct, req.test are set here
        console.log('onProxyReq triggered: ', req.test)
        proxyReq.setHeader('x-secret', req.test);
    },
    onProxyReqWs(proxyReq, req, sock, options, head) {
        // Whoops, req.test are undefined!
        console.log('onProxyReqWs triggered: ', req.test)
    }
))

I don't understand why and most importantly, HOW it bypasses middleware chain, since proxy is a middleware itself. Can you please explain this magic and advice me how to get session data from previous middlewares?

The problem is that I use it inside nuxt, which only supports low-level middlewares (e.g. only use()), so I cannot attach anything to connect app.

georgyfarniev avatar Oct 03 '19 01:10 georgyfarniev

I have met the same problem. It seems if proxy for websocket, the HPM will overwrite previous express handler. let's look at the code below:

const WsProxy = HPM(...);
DiskManager.use('/socket', function(req, res, next){
    console.log("entering first handler")
    next();
});
DiskManager.use('/socket', WsProxy);

If incoming request is websocket request, the "entering first handler" will not appear.

So weird!!! How can we solve this problem?

CrazyPandar avatar Nov 18 '19 09:11 CrazyPandar

@CrazyPandar yes, that's very disappointing since I wanted to use it for graphql with subscriptions. Graphql via http works, but subscription doesn't. Spent some time and loose some hair while debugging. Still looking for solution tho. I will let yuou know if I will find something.

georgyfarniev avatar Nov 18 '19 10:11 georgyfarniev

Any suggestions or workarounds for this one?

Edit : Had to use

server.on('upgrade', function (req, socket, head)

rohitcelestial avatar Feb 07 '20 13:02 rohitcelestial

@rohitcelestial Were you able to get this working? I'm running into this same issue, and would appreciate any insight you could share.

oortlieb avatar Feb 28 '20 19:02 oortlieb

const wsProxy = require('http-proxy').createProxyServer();
const server = app.listen(port, host)
  server.on('upgrade', function (req, socket, head) {
    sessionMiddleware(req, {}, function () {
     // access req.session data here
      wsProxy.ws(req, socket, head, {
        target: `ws://${wsHost}`,
         headers: {
             // headers
        }, 
        changeOrigin: true,
         ws: true
      });
    })
  });

  wsProxy.on('error', function (err, req, res) {
    console.log(err);
    res.end();
  });

Straight code, Hope this helps. I am sure similar can be achieved with http-proxy-middleware Thanks.

rohitcelestial avatar Mar 02 '20 14:03 rohitcelestial

anyone here got it working with http-proxy-middleware ?

MatthiasGrandl avatar Apr 15 '20 10:04 MatthiasGrandl

@MatthiasGrandl

My solution:

// configure express app however you like, then:
const server = app.listen(port)

const graphqlProxy = createProxyMiddleware({
  target: GRAPHQL_URI,
  changeOrigin: true,
  ws: true,
})

// Re-enable sessions on websockets. Middlewares are not passed to our websocket server and therefore our required `req.session` on the request is not available.
server.on("upgrade", (req, socket, head) => {
  // return a promise to make sure the session is added to the request
  // before anything else will be called.
  return new Promise((resolve) => {
    session(req, {} as any, () => {
      // req.session is now available and will be passed alongside the request
      graphqlProxy.upgrade?.(req, socket, head)
      resolve()
    })
  })
})

Hope this helps!

mrtnbroder avatar Sep 18 '20 13:09 mrtnbroder