Step 12

Notice upon successful authentication, we return the user data to the client. Of course, you don't want to include the password in that data, even when the password is hashed! Instead, a more common practice is to return a "token" to the client. A token is like a receipt that the client will keep and hand back to the server for future authentication or authorization. Conventionally, tokens have an expiration date! Once the token expires, the client must authenticate with the server again (e.g., sign in again).

Stop the application and install the jsonwebtoken package:

npm install jsonwebtoken

JsonWebToken is a popular NodeJS library that provides an implementation of Json Web Token (JWT).

Create a file, token.js in the util folder, with the following content:

const jwt = require("jsonwebtoken");

const createToken = (user) => {
  return jwt.sign(
    {
      sub: user._id,
      username: user.username,
      role: user.role,
    },
    process.env.JWT_SECRET,
    {
      algorithm: "HS256",
      expiresIn: "2d",
    }
  );
};

const verifyToken = (token) => {
  return new Promise((resolve, _reject) => {
    jwt.verify(
      token,
      process.env.JWT_SECRET,
      { algorithms: ["HS256"] },
      (err, _decoded) => {
        if (err) {
          resolve(false);
        } else {
          resolve(true);
        }
      }
    );
  });
};

module.exports = {
  createToken,
  verifyToken,
};

Notice the expiresIn attribute! It is set to expire two days after the token was created. If a token is expired (or invalid), the verifyToken will return false.

The JWT_SECRET is a string containing the secret for HMAC algorithms. You can choose any string (the longer, the better). Moreover, store this string in the .env file. (Do not forget to store the same key and value in the Heroku config variables).

The following section will use the functions exposed in token.js to employ JWT in our authentication process.

Resources