Search code examples
node.jsauthenticationcookiesrouteshttpcookie

Node.js how do you send a HttpOnly cookie after a post request (login)?


Goal/Problem

I am trying to figure out how to send a HttpOnly cookie after a post(login) request. I think I understand how to create one. The problem is that I can't create one within my post(login) route.

What I've tried

I tried creating a HttpOnly cookie on my post and it failed. Then I realized that doing a get route would create my HttpOnly cookie. I also tried doing doing a next() to my get route but I could not get it working. I also tried changing my post(login) into a get but I ran into the issue that my data passed on req.body is "undefined".

Cookie Route (using "cookie", and "express" package)

  router.get('/setcookie', (req, res)=>{ 
    res.setHeader('Set-Cookie', cookie.serialize('name', "secretcookie", {
      httpOnly: true,
      maxAge: 60 * 60 * 24 * 7
    }));
    next();
  }); 

Login Route

router.post("/login", (req, res, next) => {
    var username = req.body.username;
    var password = req.body.password;

    var sql = "SELECT * FROM user_tables where user_tables.Name = '" + username + "' AND user_tables.Password='" + password + "'";
    connectsql.query(sql, function (err, rows, fields) {
            if (rows.length === 1) {
                console.log(sql);
                console.log(rows[0].ID);
                const token = jwt.sign({P_id: rows[0].ID, P_username: username}, process.env.TOKEN_SECRET, {expiresIn: "2m"});
            } 
            else {
                console.log(sql);
                console.log("authentication failed"); //send  response of 401 for auth failed
            }
        })
})

I would appreciate the help very very much! If there is a better approach for this please let me know.


Solution

  • The handler in your login route is not returning anything. You have to set the header with the cookie in the res object and either call res.end() or next(). Assuming that your are using express it should be like this.

    const express = require('express')
    const cookie = require('cookie')
    
    const app = express()
    
    app.get('/', (req, res, next) => {
      return res.send(`<form method="POST" action="/login"><button type=submit>LOGIN!!</button></form>`)
    })
    
    app.post('/login', (req, res, next) => {
      res.setHeader('Set-Cookie', cookie.serialize('foo', 'bar', { httpOnly: true }))
      return res.send(`<body><h1>SUCCESS!!</h1></body>`);
    })
    
    app.listen(8000, () => console.log('listening'))