Ilja Ilja - 5 months ago 11
Node.js Question

Is this a good / secure way to set server side cookies from client

I am working with a single app application framework called reactjs, the issue I encountered is setting httpOnly cookies, as they can not be set / read from a client side I needed to figure out a way how to use express for this.

One idea I came up with is to make a post request to a route like

/cookie:data
where data is value of token that needs to be stored in a cookie, so:

app.post('/cookie:data', function(req, res) {
// Set cookie here
res.send(200)
})


Issue I am hesitant about is that token contains unique user identifier that is used to secure api, and I am not sure if I am or am not exposing this by setting up a cookie this way.

Alternatively instead of using
:data
it would be beneficial to figure out how I can grab data (json object) from the post request

EDIT:
One issue I can think of is that anyone can post to this route and set different cookies? what would be a way of securing it?

EDIT 2:
This is the express setup I use to proxy api calls (only relevant for clarifying comments)

app.use('/api', function (req, res) {
let url = config.API_HOST + req.url
req.pipe(request(url)).pipe(res)
})

Answer

Say that you want to proxy all requests starting with /api to a third-party, except /api/users, which you want to perform 'manually' because it returns a token you need:

app.post('/api/users', function(req, res) {
  request.post({
    // I'm making some assumptions here on how the remote API works
    url  : config.API_HOST + req.url,
    body : req.body,
    json : true,
  }, function(err, response, body) {
    // Responses are just examples, you should tailor them to your situation
    if (err) {
      return res.sendStatus(500);
    } else if (response.statusCode !== 200) {
      return res.sendStatus(response.statusCode);
    } else {
      res.cookie('token', body).send('OK');
    }
  });
})

app.use('/api', function (req, res) {
  let url = config.API_HOST + req.url
  req.pipe(request(url)).pipe(res)
})