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
}
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 }
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
}
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"
},
...
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}`);
});
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 });
}
);
});
});
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 });
});
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);
});
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.' });
});
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
Top comments (0)