JWT Authentication
A scalable JWT-based authentication system for Express with secure route protection, refresh tokens, and extendable user models.
Overview
A secure and modular JWT authentication system built for Express.js. Includes registration, login, logout, refresh tokens, and route protection. The structure follows modern best practices and supports integration with MongoDB, PostgreSQL, Prisma, or any ORM/ODM as needed. The User model and authentication logic can easily be customized or extended.
Installation
What This Does
Installs a ready-to-use JWT authentication system with routes, middleware, and secure token management for Express apps.
Files & Folders Created
| File / Path | Description |
|---|---|
| /src/routes/auth.js | Handles registration, login, refresh, logout. |
| /src/services/authService.js | Core logic for authentication and token handling. |
| /src/middleware/auth.js | Middleware for validating JWT tokens. |
| /src/models/user.js | Default user model (can be customized). |
| /src/models/tokenBlacklist.js | Optional refresh token blacklist model. |
| /src/utils/response.js | Standardized API response helper. |
Files to be modified
| File / Path | Description |
|---|---|
| server.js | Mounts /api/auth routes. |
| .env | Adds JWT configuration keys and expiration times. |
Configuration
# Environment Variables JWT_SECRET=your-super-secret-key JWT_EXPIRES_IN=15m REFRESH_EXPIRES_IN=30d # Optional if using MongoDB MONGODB_URI=mongodb://localhost:27017/backternity-app
Frontend Integration
Here’s an example of integrating the authentication routes with a Next.js frontend using React hooks and fetch API for login and protected route access.
Registers a new user and returns JWT tokens.
Authenticates user credentials and issues access/refresh tokens.
Retrieves authenticated user profile using JWT.
Revokes refresh token and logs the user out securely.
Generates a new access token using a valid refresh token.
Example
1// app/components/LoginForm.jsx
2'use client';
3import { useState } from 'react';
4
5export default function LoginForm() {
6 const [email, setEmail] = useState('');
7 const [password, setPassword] = useState('');
8 const [user, setUser] = useState(null);
9 const [error, setError] = useState(null);
10
11 async function handleLogin(e) {
12 e.preventDefault();
13 setError(null);
14
15 try {
16 const res = await fetch('/api/auth/login', {
17 method: 'POST',
18 headers: { 'Content-Type': 'application/json' },
19 body: JSON.stringify({ email, password }),
20 });
21
22 const data = await res.json();
23
24 if (!data.success) throw new Error(data.message);
25 localStorage.setItem('accessToken', data.data.token);
26 localStorage.setItem('refreshToken', data.data.refresh);
27
28 const me = await fetch('/api/auth/me', {
29 headers: {
30 Authorization: 'Bearer ' + data.data.token,
31 },
32 });
33
34 const userData = await me.json();
35 setUser(userData);
36 } catch (err) {
37 setError(err.message);
38 }
39 }
40
41 return (
42 <div className="max-w-sm mx-auto bg-black/20 border border-white/10 rounded-xl p-6 text-white space-y-4">
43 <h2 className="text-xl font-semibold">Login</h2>
44 <form onSubmit={handleLogin} className="space-y-3">
45 <input
46 type="email"
47 value={email}
48 onChange={(e) => setEmail(e.target.value)}
49 placeholder="Email"
50 className="w-full px-3 py-2 rounded-md bg-white/10 border border-white/20 focus:outline-none"
51 required
52 />
53 <input
54 type="password"
55 value={password}
56 onChange={(e) => setPassword(e.target.value)}
57 placeholder="Password"
58 className="w-full px-3 py-2 rounded-md bg-white/10 border border-white/20 focus:outline-none"
59 required
60 />
61 <button
62 type="submit"
63 className="w-full bg-emerald-500 hover:bg-emerald-600 text-white font-semibold py-2 rounded-md transition-colors"
64 >
65 Sign In
66 </button>
67 </form>
68
69 {error && <p className="text-red-400 text-sm">{error}</p>}
70 {user && (
71 <div className="mt-4 p-3 bg-emerald-500/10 rounded-lg border border-emerald-500/20">
72 <p className="text-sm text-emerald-300">Welcome, {user.email}</p>
73 </div>
74 )}
75 </div>
76 );
77}Usage
1// Protecting routes in Express
2const express = require('express');
3const { validateAuth } = require('./src/middleware/auth');
4const app = express();
5
6app.get('/api/protected', validateAuth, (req, res) => {
7 res.json({ message: 'Access granted', user: req.user });
8});