top of page
Search
  • Writer's picturealeksvp

How to protect Node server endpoints, checking for JSON Web Tokens




Full code: https://github.com/aleksvp2017/secureroutes

Using:

  • Node.js;

  • Express;

  • express-bearer-token;

  • jsonwebtoken


I'm assuming that you have a Node server running express with a couple of routes set (if you need, there is a post about that here). The full code example is set up like that.


So, the main idea is to configure which routes you want to be secure (by secure, I mean, routes that demand authentication, which is going to be checked by the presence of a token), then, we're going to set a middleware that checks every request: if it requires authentication, we're going to check if there is a valid token (you can, and probably should, also check for permissions for a particular user too).


So, first step, is to configure the routes that would require authentication. In routes.js, going to add a property like that:

var routes = [ { uri: '/login', httpmethod: 'post', component: Permision, method: 'login', requireAuthentication: false}, { uri: '/products', httpmethod: 'get', component: Product, method: 'list', requireAuthentication: true}, ]


Next step is creating a js to check for the presence of the token, in my example, permision.js:

const checkForToken = (req, res, next) => { var Routes = require('../routes/routes.js') if (Routes.requireAuthentication(req.originalUrl, req.method)){ var jwt = require('jsonwebtoken') jwt.verify(req.token, process.env.SECRET, async (err, decoded) => { if (err) { res.status(440).send({error: err}) } else { next() } }) } else{ next() } } const login = async function (req, res, next) { var jwt = require('jsonwebtoken') let token = jwt.sign({ email: req.body.user.email }, process.env.SECRET, { expiresIn: 86400 //24h }) res.status(200).json({ auth: true, usuario: { ...req.user, token: token}}) next() } module.exports = { checkForToken, login }


So, basically it checks if the route require authentication, and if so, try to read the token generated with a particulary secret. I set the secret using (on VisualCode terminal, same that is going to be used to run the app):

$env:SECRET='mySecret'.


The "next()" call is important because, as you know, express is in fact a series of middlewares, so you have to do this to maintain the middleware's flow.


So if you run the app (nodemon app.js) and try to access http://localhost:3001/products you're going to get a error:

{

"error": {

"name": "JsonWebTokenError",

"message": "jwt must be provided"

}


You can generate the token in various ways. For instance, using https://jwt.io/, like this:


But, as you must have noticed, I provided an endpoint to do that (http://localhost:3001/login). All you have to do is post a request passing something like that (on the body, as json):

{"user" : {

"email": "aleksvp@gmail.com"

}}


Of course, I didn't really check the user in a database or anything like that, didn't even required a password. In a real case, you should.


Once you have the encoded token, on the request, you must include, as a header parameter:

Key:Authorization Value: Bearer <<tokenValue>>



That's pretty much it. Easy stuff, right?











35 views0 comments

Comments


Post: Blog2_Post
bottom of page