Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing Token from API w/ Express http-proxy

I'm setting up a universal React app and using this project as a base. I am successfully proxying requests (using http-proxy) to my Laravel backend. However, I'm new to Nodejs and I don't know how the best method to securely store a JWT from the proxied server to the client.

My initial thought was to store the token to localStorage, but the problem is that the express server won't have access to it. So my next guess would be to store it as a cookie, but I'm not sure how to store it on the client or include it as a header for all outgoing requests (additionally, I would likely need some sort of csrf middleware).

So how would I manipulate the response from my api server to put a token in a cookie that is set in the client, then use that as a bearer token for all api requests?

// server.js
const targetUrl = 'http://' + config.apiHost + ':' + config.apiPort;
const app = new Express();
const server = new http.Server(app);

const proxy = httpProxy.createProxyServer({
  target: targetUrl,
  changeOrigin: true
});

// Proxy to Auth endpoint
app.use('/auth', (req, res) => {
  // on a successful login, i want to store the token as a cookie
  proxy.web(req, res, {target: targetUrl});
});

// Proxy to api endpoint
app.use('/api', (req, res) => {
  // use the token in the cookie, and add it as a authorization header in the response
  proxy.web(req, res, {target: targetUrl});
});
like image 671
csm232s Avatar asked Sep 26 '22 09:09

csm232s


1 Answers

Given that the response from the auth endpoint in laravel is like this:

{ 
    "token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
}

This code will do what you want:

// server.js
const targetUrl = 'http://' + config.apiHost + ':' + config.apiPort;
const Express = require('express');
const http = require('http');
const httpProxy = require('http-proxy');
const app = new Express();
const server = new http.Server(app);
const Cookies = require( "cookies" )

const proxy = httpProxy.createProxyServer({
  target: targetUrl,
  changeOrigin: true
});

// Proxy to Auth endpoint
app.use('/auth', (req, res) => {
  // on a successful login, i want to store the token as a cookie
  // this is done in the proxyRes
  proxy.web(req, res, {target: targetUrl});
});

// Proxy to api endpoint
app.use('/api', (req, res) => {
  // use the token in the cookie, and add it as a authorization header in the response
  var cookies = new Cookies( req, res )
  req.headers.authorization = "JWT " + cookies.get('jwt-token');
  proxy.web(req, res, {target: targetUrl});
});

proxy.on('proxyRes', function(proxyRes, req, res) {
    if (req.originalUrl === '/auth') {
        var cookies = new Cookies( req, res )
        var body = '';
        var _write = res.write;
        var _end = res.end;
        var _writeHead = res.writeHead;
        var sendHeader = false;

        res.writeHead = function () {
            if (sendHeader) {
                _writeHead.apply( this, arguments );
            }
        }
        res.write = function (data) {
            body += data;
        }
        res.end = function () {
            sendHeader = true;
            var parsed = JSON.parse(body);
            cookies.set('jwt-token', parsed.token);
            _write.apply(this, [ body ]);
            _end.apply(this, arguments);
        }

    }
});
like image 65
bolav Avatar answered Sep 28 '22 06:09

bolav