Secure API (backend)

In this guide, you will learn how to secure your API endpoints in Node (Express).

1. Install the required dependencies

Open your console, navigate to your backend project and execute the appropriate command.

npm install passport passport-jwt

2. Add an authentication middleware

Hint: You can also try out our NodeJS sample app.

  1. Add the following code into the file where you create your Express app (usually app.js).
// app.js

const Express = require('express');
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const jwksRsa = require('jwks-rsa');

// ...
// const app = new Express();
// ...

// verifying all authenticated users (default):
const verify = (jwt_payload, done) => {
  if (jwt_payload && jwt_payload.sub) {
    return done(null, jwt_payload);
  }
  return done(null, false);
};

passport.use(
  new JwtStrategy({
    secretOrKeyProvider: jwksRsa.passportJwtSecret({
      cache: true,
      rateLimit: true,
      jwksRequestsPerMinute: 5,
      jwksUri: 'https://firstline.sh/.well-known/jwks.json'
    }),
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),

    audience: 'API_IDENTIFIER',  // TODO: replace
    issuer: 'DOMAIN',  // TODO: replace
    algorithms: ['RS256']
  },
  verify)
);

// make sure the Express app is created above
app.use(passport.initialize());

// ...
// app.listen(port, () => console.log(`App listening on port ${port}`))
// ...
  1. Replace the API_IDENTIFIER with the identifier you configured in the API you created (e.g. http://localhost:8080). This must be identical to the identifier you use as audience in the frontend.
  2. Replace the DOMAIN with your Firstline domain.

You can find both in the "Configure" tab of your create API.

3. Define secure API endpoints

Now you can define secure endpoints that are only accessible to authenticated users.

// returns the authenticated user:
app.get('/me', passport.authenticate('jwt', { session: false }), (req, res) => {
  res.json(req.user);
});

// returns posts:
app.get('/posts', passport.authenticate('jwt', { session: false }), (req, res) => {
  res.json([
    { id: 0, text: "Be extremely subtle, even to the point of formlessness." },
    { id: 1, text: "The supreme art of war is to subdue the enemy without fighting." },
    { id: 2, text: "If you know the enemy and know yourself you need not fear the results of a hundred battles." }
  ]);
});