02 - Validate Session
In this module, we'll construct a file that will check to see if the request has a token attached.
Files
Please add the following to your server in the middleware folder:
└── 5-Express Server
└── server
└── controllers
└── middleware
└── headers.js
└── validate-session.js <----- ADD THIS
└── models
└── clientCode
Put the following code inside of validate-session.js. There is a little bit of code that is commented out here, leave it like that for now.
var jwt = require('jsonwebtoken');
var sequelize = require('../db');
var User = sequelize.import('../models/user');
module.exports = function(req, res, next) {
// if (req.method == 'OPTIONS') {
// next()
// } else {
var sessionToken = req.headers.authorization; //1
console.log(sessionToken) //2
if (!sessionToken) return res.status(403).send({ auth: false, message: 'No token provided.' }); //3
else { //4
jwt.verify(sessionToken, process.env.JWT_SECRET, (err, decoded) => { //5
if(decoded){
User.findOne({where: { id: decoded.id}}).then(user => { //6
req.user = user; //7
next();
},
function(){ //8
res.status(401).send({error: 'Not authorized'});
});
} else { //9
res.status(400).send({error: 'Not authorized'});
}
});
}
//}
}What Just Happened?
There's a lot here, so take it slow through this explanation. Additional information on the verify method can be found here.
The variable
sessionTokenis created to hold the token, which is pulled from the authorization header of the request coming in.The token is printed to the console. This is purely for debugging purposes to verify that the token is being sent to the server. It should not be left in the final code, as it is a potential security vulnerability.
If no token is present, the
403 Forbiddenerror is returned as the response. We have several different error handling responses in this file, so assigning each a different error code or message is a big help in debugging.No
userproperty is ever provided in the request, so only tokens will get checked. This prevents unauthorized use of a token that was assigned to a different user.The
verifymethod decodes the token with the provided secret, then sends a callback with two variables. If successful,decodedwill contain the decoded payload; if not,decodedremainsundefined.errisnullby default.If
decodedhas a value, the SequelizefindOnemethod looks for anidin theuserstable that matches thedecoded.idproperty. This value is then passed into a callback.The callback sets the
uservalue for the request as theidvalue passed to it then sends the request on to its next destination. This property will be necessary later in adding to the database.If no matching
idis found, an error message is thrown.If no value for
decoded, an error message is thrown.
Before You Move On
Go back and read through all that again. Make a flow chart of what's happening. Explain to a partner what is going on. Do whatever you need to do in order to understand this file. This is some very deep, very detailed code that can be tough to understand. Security should be your #1, #2, and #3 priorities when coding, so it's worth the extra time to get it right.
Last updated