Persisting a cookie based session over node-http-proxy
Asked Answered
L

5

13

I have a simple Express based Node.js web server that I'm using for development of a JavaScript application. I set up the server to use node-http-proxy to proxy API requests the application makes to a Jetty server that is running on a different domain and port. This setup has been working flawlessly until I started to run into problems with session management.

Upon authentication the application server returns a cookie with an auth token representing the server session. When I run the JS application off of my filesystem (file://) I can see that once client receives the cookie, it is sent in all the subsequent API requests. When I run the JS app on the node server and API calls are proxied through node-http-proxy (RoutingProxy) the request headers never include the cookie.

Is there something I need to handle manually to support this type of session persistence through the proxy? I've been digging through the node-http-proxy code but it is a little over my head because I am new to Node.

https://gist.github.com/2475547 or:

var express = require('express'),
    routingProxy = require('http-proxy').RoutingProxy(),
    app = express.createServer();

var apiVersion = 1.0,
    apiHost = my.host.com,
    apiPort = 8080;

function apiProxy(pattern, host, port) {
    return function(req, res, next) {
        if (req.url.match(pattern)) {
            routingProxy.proxyRequest(req, res, {host: host, port: port});
        } else {
            next();
        }
    }
}

app.configure(function () {
    // API proxy middleware
    app.use(apiProxy(new RegExp('\/' + apiVersion + '\/.*'), apiHost, apiPort));

    // Static content middleware
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(express.static(__dirname));
    app.use(express.errorHandler({
        dumpExceptions: true, 
        showStack: true
    }));
    app.use(app.router);
});

app.listen(3000);
Laughter answered 24/4, 2012 at 2:28 Comment(0)
D
5

I did what you are asking by manually looking at the response, seeing if it is a set-cookie, snipping off the JSESSSIONID, storing it in a variable, and passing it on all subsequent requests as a header. This way the reverse proxy acts as a cookie.

on('proxyReq', function(proxyReq){ proxyReq.setHeader('cookie', 'sessionid=' + cookieSnippedValue) 
Depravity answered 29/8, 2015 at 10:54 Comment(0)
C
2

Hi @tomswift does your local server run on http protocol, but the session cookie receive from the remote server carry with Secure; like:

'set-cookie':
[ 'JSESSIONID=COOKIEWITHSECURE98123; Path=/;HttpOnly;Secure;']

If so, before your local server response to the client, extract set-cookie from the original response(response from remote server to local server) header, remove the Secure; and put the rest of it into the proxy response (response from local server to client ) header like:

'set-cookie':
[ 'JSESSIONID=COOKIEWITHSECURE98123; Path=/;HttpOnly;']

then the client will take the session cookie automatically.

Hope it may help.

Companionate answered 18/9, 2016 at 3:14 Comment(2)
Thank you for mentioning this @Companionate removing the secure flag also solved my issue specifically related to JSESSIONIDSchmaltzy
Be careful when removing the "secure" flag. That means that cookies will be sent over insecure connections, and could be exposed to packet sniffers, potentially giving away the user's login creds, or sensitive session information!Vermiculate
B
0

Ideally the job of a proxy is to just forward a request to the destination, and should not strip off critical headers like cookies, But if it is, i think you should file a issue against them here https://github.com/nodejitsu/node-http-proxy/issues.

Also you said the request headers never include the cookie, Is it possible the client never received it?

Barsac answered 24/4, 2012 at 2:56 Comment(2)
I have confirmed in Web Inspector that the client recieves the 'set-cookie' header. You can see the transaction here. The request cookie in this case is being generated by Express's cookieParser which I was trying to use to support the session but it seems to always do its own thing.Laughter
Opened an issue in GitHub as I struggle to try and get the cookie from the proxied server's response and manually support the session: github.com/nodejitsu/node-http-proxy/issues/236Laughter
L
0

I found a way to implement this by forking and modifying node-http-proxy. It serves my current purpose which is a development environment. For any sort of serious consideration it needs to be fleshed out into a more legitimate solution.

The details can be found in the issue I filed in GitHub: https://github.com/nodejitsu/node-http-proxy/issues/236#issuecomment-5334457

I would love some input on this solution, especially if I'm going completely in the wrong direction.

Laughter answered 25/4, 2012 at 22:2 Comment(0)
E
0

I had similar problems that cookies were not passed forward to the client. Solution:

  1. get cookie from proxy response
  2. set it in proxy request, with slightly modified value
let cookie;
const webpackConfig = {
  proxy: {
    '/api': {
        ...
        onProxyReq: (proxyReq) => {
          if(cookie) {
            proxyReq.setHeader('Cookie', cookie);
          }
        },
        onProxyRes: (proxyRes) => {
          const sc = proxyRes.headers['set-cookie'];

          const raw = sc.filter(s => s.startsWith('JSESSIONID'));

          if(raw.length) {
            cookie = raw[0].split(';')[0];
          }
        }

    }
  }
}
Encrimson answered 11/4, 2019 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.