Marcin Buglewicz Marcin Buglewicz - 3 months ago 14
Node.js Question

Securing rest api with jwt

I've been trying to secure my rest api with authentication so only trusted apps could consume this api. I've been looking for best practices and guides but none of them actually explains that in real-world example.

I created jsonwebtoken authentication similar to this:

res.json({success:false, message: 'auth failed, user not found'});
} else {
var token = jwt.sign(user, app.get('superSecret'), {
expiresIn: 1440 //24 hours
success: true,
message: 'token generated',
token: token

This works ok, returning a token which I can then pass with all requests to an api, but how do I make the app find that token and use it instead manually pass token every api call?

I've seen that in most of the time, you can generate special api-key within the app and include that info in client's app which works kind of like a token and there is no need to request new token from server.

How does that work or how do I create trusted apps keys for my restful service?


Using JWT is perfectly fine, in fact I use it myself. But the way you're using it in your example is not very secure. JWTs are not encrypted, but rather just encoded. If you're sending this token to someone and including sensitive information such as superSecret, anybody with access to the token will be able to decode this.

A cleaner idea is to attach this token to a session object. If you're using Node.js and Express then you can use the express-session library. This attaches a session object to each request. Once a user is authenticated you can assign this token to the session object and store it either in a database or memory store such as redis. For an additional layer of security you can generate an api-key for each trusted app and store that in your database. The api-key can be passed through as a header.

To set up sessions with Express, but I do suggest you read up on other options and ways to configure this to your needs:

var session = require("express-session");
        secret: /* Your secret. */,
        store: /* Your redis store object. */,
        client: /* Your redis client object. */,
        resave: false,
        saveUninitialized: false

To attach the access-token to the user on login (for example):"/login", function(request, response){

    /* Do all user validation here */

    request.session.token = jwt.sign({
            /* User info to store in session. */
    }, "superSecret");

    return response.redirect( /* Dashboard */ );


The way you would authenticate a user then would be:

  1. Validate that the api-key is valid.
  2. Check if(!user.session){ // Route to login page. }
  3. Check if(!user.session.token){ // Not authorized. }
  4. Validate user.session.token
  5. Using the credentials inside the token (do NOT put the users password in here), validate that the user is a valid user in your system - assuming that they have registered an account on your website/platform. You can for instance store permission levels and userIds with an email address or something that you would use for validation.

I hope this helps! It takes a while to wrap your head authentication practices.