DEV Community

Giancarlo Ramirez
Giancarlo Ramirez

Posted on

Express & JWT demo server

Repo: https://github.com/zendostrike/express-jwt-demo-server

Hello, let's create a simple Express + JWT demo server you can use in your demo projects.

First of all, let's create a new directory for our project:
mkdir express-jwt-demo-server && cd express-jwt-demo-server

Init npm
npm init -y

Install express library.
npm install express

Install jsonwebtoken library.
npm install jsonwebtoken

Install sqlite3 library to save your users.
npm install sqlite3


Database

Let's create a database.js file and create a database and a Users table using sqlite3.

const sqlite3 = require('sqlite3');

const db = new sqlite3.Database('database.db');

db.run(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    email TEXT NOT NULL,
    password TEXT NOT NULL,
    name TEXT,
    lastName TEXT
  )
`);

module.exports = {
  db
}
Enter fullscreen mode Exit fullscreen mode

Secret

Create a constants.js file to save the JWT secret. You can use any string as your secret taking into account that this only for demo purposes.

const secretKey = 'a1521a878991a0941572eafc7708c7cb00756dd8d6844dbb9cc294c74e2108dfa09df9140c0fff6bc6a1e35e8be4b5b4e7bf79b7470fbfaadbb37d61ec6afb6f';

module.exports = { secretKey }
Enter fullscreen mode Exit fullscreen mode

Middleware

Create a verify-token.js file. This is going to be our middleware in charge of verify token.

const jwt = require('jsonwebtoken');
const { secretKey } = require('../constants');

function verifyToken(req, res, next) {
  const token = req.headers.authorization;

  if (!token) {
    return res.status(401).json({ error: 'Unauthorized: No token provided' });
  }

  jwt.verify(token.split(' ')[1], secretKey, (err, decoded) => {
    if (err) {
      return res.status(401).json({ error: 'Unauthorized: Invalid token' });
    }

    // Store the decoded token data in the request for future use
    req.user = decoded;
    next();
  });
}

module.exports = {
  verifyToken
}
Enter fullscreen mode Exit fullscreen mode

Package.json scripts

Let's modify our package.json scripts to run our project (you can use --watch to hot reload the project when code is changed):

  ...
  "scripts": {
    "start": "node --watch index.js"
  },
  ...
Enter fullscreen mode Exit fullscreen mode

Express app

Create a index.js file importing our other files and create a new express app running at port 3000.

const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const { verifyToken } = require('./verify-token');
const { secretKey } = require('./constants');
const { db } = require('./database');

const app = express();
const port = 3000;

// Middleware for parsing JSON request bodies
app.use(bodyParser.json());

// Start the Express server
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Cool, if you run npm start you will see the server running.
Now we need some routes.

Create a Register route

  • It takes name, lastName, email and password to create a new user.
  • If email or password missing will return an error.
  • If email already used will return an error.
  • Attemps creating a new user, if fails return error, if success JWT creates a new token using user's information and the secret.
// Endpoint to register a new user and generate a JWT token
app.post('/register', (req, res) => {
  const { name, lastName, email, password } = req.body;

  if (!email || !password) {
    return res.status(400).json({ error: 'Email and password are required' });
  }

  // Check if the user with the same email already exists in the database
  db.get('SELECT * FROM users WHERE email = ?', [email], (err, existingUser) => {
    if (err) {
      return res.status(500).json({ error: 'Database error' });
    }

    if (existingUser) {
      return res.status(409).json({ error: 'Email already in use' });
    }

    // If the email is not already in use, proceed with user registration
    // Insert the new user into the database
    db.run(
      'INSERT INTO users (name, lastName, email, password) VALUES (?, ?, ?, ?)',
      [name, lastName, email, password],
      (err) => {
        if (err) {
          return res.status(500).json({ error: 'Error registering user' });
        }

        // Generate a JWT token for the registered user
        const token = jwt.sign({ name, lastName, email }, secretKey, { expiresIn: '1h' });

        res.status(201).json({ message: 'User registered successfully', token });
      }
    );
  });
});
Enter fullscreen mode Exit fullscreen mode

Create a Login Route

  • It will recieve email and password
  • If wrong email or password returns an error.
  • If correct user and password will create a token and returns it.
app.post('/login', (req, res) => {
  const { email, password } = req.body;

  if (!email || !password) {
    return res.status(400).json({ error: 'Email and password are required' });
  }

  // Generate a JWT token for the logged-in user
  const token = jwt.sign({ email }, secretKey, { expiresIn: '1h' });

  res.status(200).json({ message: 'Login successful', token });
});
Enter fullscreen mode Exit fullscreen mode

Create a route for getting Logged User

It will all the information from the access token. You will have to add Bearer token to your request to get a correct response.

app.get('/user', verifyToken, (req, res) => {
  res.status(200).json(req.user);
});
Enter fullscreen mode Exit fullscreen mode

Finally create a protected route to test our token.

app.get('/protected', verifyToken, (_, res) => {
  // If the middleware (verifyToken) has passed, it means the token is valid
  res.status(200).json({ message: 'OK, you have a valid token.' });
});
Enter fullscreen mode Exit fullscreen mode

Now you can test your frontend project and build a sessions based on JWT access token.

Repo: https://github.com/zendostrike/express-jwt-demo-server

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay