How to add authentication to the API routes of an ExpressJS app

How to add authentication to the API routes of an ExpressJS app

There are a couple of different approaches that we can use in order to add an authentication layer to the API routes of our ExpressJS app.

There are a couple of different approaches that we can use in order to add an authentication layer to the API routes of our ExpressJS app.

The problem

When we create API routes to be consumed by a web client, we're actually exposing those routes to the world.

There is absolutely no guarantee that the calls to these routes come from a legitimate origin. This is a big security risk.

In order to fix this problem, we need to add an authentication layer to our routes.

Sessions

If our routes require an authenticated user in order to be processed, we can follow these steps.

  1. In a middleware function, we check the session object to see whether there is a reference to the current user..
  2. If so, we process the incoming request.
  3. Otherwise we send an error message along with the appropriate HTTP status code.
'use strict';

const isAuthenticated = (req, res, next) => {
    if(req.originalUrl.includes('/api') && !req.session.user) {
        res.status(401).send({error: 'Unauthorized'});
    }
    next();
};

module.exports = isAuthenticated;

Then we apply our middleware logic to ExpressJS:

'use strict';

const app = require('express')();
const isAuthenticated = require('./middleware/isAuthenticated');
app.use(isAuthenticated);
app.listen(8080);

The above code adds the authentication process to all the API routes of our app.

HTTP headers

This approach is similar to the previous one, except that now we're verifying that a custom HTTP header is actually set when a client sends its request.

We can modify our validation process as follows:

'use strict';

const isValidHttpHeader = (name, value, request) => {
    return (request.headers[name] && request.headers[name] === value);
};

const isAuthenticated = (req, res, next) => {
    if(req.originalUrl.includes('/api') && isValidHttpHeader('Custom-Auth-Header', 'secret', req)) {
        res.status(401).send({error: 'Unauthorized'});
    }
    next();
};

module.exports = isAuthenticated;

By doing so, any web client needs to add a specific header that will be later validated by our middleware code.