Christian Giacomi

An attempt at a small developer blog

Bearer strategy in Express.js

Posted at — Aug 12, 2018

When working with Express.js you will at some point require some kind of authentication. In my case, since I have moved away from server side rendering and use Angular for the front-end and Express.js or Hapi for my REST API, I choose to use JWT tokens for my authentication needs.

I will not cover JWT tokens as it would make this post much longer and also because there are so many awesome posts about it out there, like this blog post by Flavio Copes.

So what can you use for Express when you want your front end to authenticate requests via a JWT token? Well the de facto standard is Passport.JS.

Passport.js as the official documentation states is:

“Passport is authentication middleware for Node.js. Extremely flexible and modular…”

Modular is the keyword here, as the middleware contains hundreds of different strategies which can be used, depending on your needs.

Because of my requirements I will focus on Passport’s Bearer strategy, and how you can integrate it with your Express backend.

Bearer Auth

Bearer auth, or token authentication, is an HTTP authentication scheme which comprises security tokens called bearer tokens. The token is usually a cryptic string, and is generated in response to a successful login on the part of a user.

A client must include this token in the Authorization header when making requests to any protected resource on the server. As I have stated I use JWT tokens but of course you can use any type of token you choose.

Lets start by installing Passport.js

npm install passport

At this point we can include the Bearer strategy in our code, the middleware configuration code looks like this:

passport.use(new BearerStrategy(
  function(token, done){
    // Validation logic here

    return done(null, user, { scope: 'read' });
  }
));

When calling done you can optionally pass the scopes, like you see above, for later use in your backend.

So let’s add a sample authentication logic to our config code. I will of course also use a JWT token module to help me out. I personally prefer jwt-simple which can be found here

npm install jwt-simple

Lets use the JWT module with the bearer strategy config.

var jwt = require('jwt-simple');
var User = require('./models/user.js'); // Sample user model


passport.use(new BearerStrategy(
  function(token, done){
    try {
      //we attempt to validate the token the client sent with the request
      var decoded = jwt.decode(token, MY_JWT_SECRET);

      // Check that the token has not expired
      // if expired return done(null, false);
      
      // Find the user represents by the subject claims
      User.findOne({ email: decoded.sub }, function (err, user) {
        if (err) { return done(err); }
        if (!user) {
          return done(null, false); //no such user
        }
        else {
          return done(null, user); //allows the call chain to continue to the intented route
        }
      });
    }
    catch(err){
      return done(null, false); //returns a 401 to the caller
    }
  }
));

That is all. The code above will intercept all requests that require authentication and will first of all validate the token. If the token is valid you can then look up the user in the database and call done with the actual user. Or if for some reason you need to return an error or the user does not exist in the database you will need to call done passing an error.

Authenticated Route

To lock your route and access an authenticated user you will need to simply specify that the route requires authentication and then you can gain access to the user by calling req.user .

app.get('/secure', passport.authenticate('bearer', { session: false }), function(req, res, next){
  // Get the authenticated user.
  var user = req.user;

  // Route implementation here...
});

To disable session support and ensure we do not set any cookies you can use { session: false } in the call to passport.

JWT Token

Ok so how can you store your token client side and still maintain security?

The token can be easily stored in session storage or local storage because they are sand boxed and not accessible by other sites or scripts.

A proper authentication server will usually return both an access token and a refresh token when a user authenticates.

Access token will normally be short lived, no more than 24hrs. While a refresh token will be long lived and will be used to gain a new access token when the token has expired. This ensures that a user does not need to authenticate often, but at the same time it allows the backend to black list and deny access to a user.

Disclaimer: The code above is only meant for documentation purposes and is NOT production ready. Kindly refer to Passport.js and Jwt-Simple’s documentation.