Node.js: Send new request with token(JWT) in URL after logging in Node.js: Send new request with token(JWT) in URL after logging in mongoose mongoose

Node.js: Send new request with token(JWT) in URL after logging in


OK, so I'll try and answer your question even though I'm not 100% sure I understand what you're asking. The basic flow of a JWT is that the user logs in, and you issue it. You don't store it because the whole point of a JWT is that there's no overhead on the server for storing it (allowing for a more distributed approach to user management). The exception is if you want to do a logout feature, but that doesn't look like it's one of your requirements.

From the standpoint of responsibilities, you should have a Login function or module which is responsible for verifying a user's credentials and issuing a token. You should have a Verification function or module that validates the token and places the decoded token on the request object for later use (no need to repeatedly decode). And you may (or may not) have an Authorization module that validates that a given user is allowed to perform a given task.

So, from the top. Note that you can let the DB do the query work rather than doing your own loop. I'm also assuming that your User schema will include a verifyPassword method that takes care of comparing salted and hashed passwords.

// loginrouter.post('/login', function (req, res, next) {      // note I didn't use lean() because I want access to User methods. Performance is less of an issue in my version, b/c the DB is only retrieving one user at most.       User.findOne({ username: req.body.username }).exec(function (err, user) {          if(err) return next(err);           if(!user) return res.status(401).send();          if (user.verifyPassword(req.body.password)) {                  // maybe add more info about the user, like display name                  var token = jwt.sign({username:user.username}, secret, {expiresIn:'1h'});                  return res.status(200).send({message: 'You are now signed in', token: token});             }          }                 return res.status(404).send({ error: 'Invalid username or password: ' + req.body.username });      });  });

Now the client will have access to the token more easily, and can send it on further requests.

// verifymodule.exports = function  (req, res, next) {  // this is fine, though I think the standard is that the token should be sent in the Authorization header with the format Bearer {token}  var token = req.body.token || req.headers['x-access-token'] || req.query.token;  if(!token) {    return next(); // this middleware just is responsible for decoding, other middleware checks authorization  } else {    jwt.verify(token, secret, function(err, decode) {        if(err) {            return next(); // again, a bad token doesn't necessarily mean anything for some application pages, put the logic elsewhere.         } else {            req.user = decode; // this will be { username } based on above            req.token = token; // generally you don't need it but just in case.             next();        }    });   } }

Ok, so now further middleware will include a req.user that you can use to check if a given user should be allowed to see a resource or not. For example:

function userRequired(req, res, next) {  if (!req.user) return res.status(401).send({message: 'You must be logged in to view this page' });  return next();}

This scales well to other checks, you could have one for various roles, etc.