Search code examples
node.jshandlebars.jsjwtexpress-jwt

passing jwt in header


I have created a project in nodejs to check how jwt works. I have put authentication on a route I am able to validate with postman. Although I want that validated route to render a page if the user is logged in. I am using handlebars.js for templating. Can anyone help me how to make this happen.

index.js (Route)

var ctrlUsers = require('../controllers/users.controllers.js');
router
.route('/users/login')
.post(ctrlUsers.login);

app.use(ctrlUsers.authenticate);
.get(ctrlUsers.authenticate,ctrlUsers.showaddress);

module.exports = router

users.controller.js

module.exports.login = function(req, res) {
console.log('logging in user');
var username = req.body.username;
var password = req.body.password;
User.findOne({
username: username
})
.exec(function(err, user) {
if (err) {
  console.log(err);
  res.status(400).ender('error');
} 
 else {
  if (bcrypt.compareSync(password, user.password)) {
    console.log('User found', user);
    var token = jwt.sign({ username: user.username }, 's3cr3t', { expiresIn: 3600 });
    console.log("Token1" + token);
    res
    .status(200)
    .redirect('/');
  } else {
    res
    .status(401)
    .render('error');
  }
  }
  });
  };

  module.exports.showaddress = function(req, res) {
  res.render('index');
  console.log("I am in");
  console.log(req.user);
  }


 module.exports.authenticate = function(req, res, next) {
 var headerExists = req.headers.authorization;
 console.log(headerExists);
 if (headerExists) {
 var token = req.headers.authorization.split(' ')[1]; 
 jwt.verify(token, 's3cr3t', function(error, decoded) {
  if (error) {
    console.log(error);
    console.log("Token 2" + token);
    res.status(401).json('Unauthorized');
  } 
  else {
    req.user = decoded.username;
    console.log("Here");
    next();
  }
 });} else { console.log("Token 3" + token) res.status(403).json('No token provided'); } };

On checking with Postman this works fine. I am just not sure how to make it work on browser. Like it should show me a page when I hit "http://localhost:3000/users/showaddress" when logged in.

Can anyone please help with this.


Solution

  • Quick answer is, send the JWT via a cookie instead of a header, and the browser will do the job for you.

    Note that this is only possible if you only have web clients. To support native clients too, you basically need to either airways send the JWT in a header, or let the client specify whether it wants it in a header or cookie. Native clients doesn't handle cookies that well.

    If you want to stick with the header, you need a network layer in your client (JavaScript) application that adds the JWT as a header to each outgoing request to the server that issued the JWT. (Make sure to store the JWT in a secure storage in the client. Using cookies, you get this for free too.)

    You probably med this layer anyway depending on how the backend behaves when a JWT expires. A common setup is that the client needs to detect when the JWT is expired (backend typically responds 401) and (try to) login again in the background.