Unlocking the Power of JSON Web Tokens: A Comprehensive Guide

What is a JSON Web Token?

A JSON Web Token (JWT) is an open standard that enables developers to verify the authenticity of claims via a signature. This signature can be either a secret or a public/private key pair. JWTs are widely used for authentication and secure transmission of information between parties.

How Does JWT Authentication Work?

In JWT-based authentication systems, when a user logs in successfully, a JSON Web Token is returned to the client. The client then includes this token in the Authorization header of subsequent requests to access protected resources. The server verifies the token and grants access if it’s valid.

Building a Node.js Application with JWT Authentication

To demonstrate JWT authentication with a Node.js backend and a Vue.js frontend, we’ll build a simple application. First, we’ll set up the backend using Express, Babel, and PostgreSQL.

Folder Structure

Our application will have a monorepo structure, with separate folders for the client and server code.

client/
server/
app.js
models/
user.js
routes/
auth.js
index.js
package.json

Server Setup

We’ll create a basic Express server that handles user authentication and returns a JWT token upon successful login. The server will also verify the token on subsequent requests.

const express = require('express');
const app = express();

app.post('/login', (req, res) => {
  const user = { id: 1, name: 'John Doe' };
  const token = jwt.sign(user, process.env.SECRET_KEY, { expiresIn: '1h' });
  res.json({ token });
});

app.get('/protected', authenticate, (req, res) => {
  res.json({ message: 'Hello, authenticated user!' });
});

function authenticate(req, res, next) {
  const token = req.header('Authorization');
  jwt.verify(token, process.env.SECRET_KEY, (err, decoded) => {
    if (err) return res.status(401).send({ message: 'Invalid token' });
    req.user = decoded;
    next();
  });
}

Client Setup

On the client-side, we’ll use Vue.js and the vue-jwt-decode library to decode the JWT token and authenticate the user.

import Vue from 'vue';
import VueJwtDecode from 'vue-jwt-decode';

Vue.use(VueJwtDecode);

export default {
  mounted() {
    const token = localStorage.getItem('token');
    if (token) {
      const decoded = VueJwtDecode.decodeToken(token);
      console.log(decoded);
    }
  },
};

Generating and Verifying JWT Tokens

We’ll explore how to generate JWT tokens using a private key and verify them using a public key. We’ll also discuss the structure of a JWT token, which consists of a header, payload, and signature.

const privateKey = `-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----`;

const publicKey = `-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----`;

const payload = { sub: '1234567890', name: 'John Doe', admin: true };
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

const verified = jwt.verify(token, publicKey);
console.log(verified);

Tokens and Refresh Tokens

Tokens give users access to protected resources, while refresh tokens allow users to request new tokens when the existing one expires.

  • Access Tokens: short-lived tokens used to access protected resources
  • Refresh Tokens: long-lived tokens used to request new access tokens when the existing one expires

Deploying to Heroku

Finally, we’ll deploy our application to Heroku, using a Postgres database and configuring the necessary environment variables.

heroku create my-app
heroku addons:create heroku-postgresql:hobby-dev
heroku config:set SECRET_KEY=my_secret_key
git push heroku master

Leave a Reply