Guide to Secure Authentication with Express.js JWT
What Will You Learn in This Guide?
In this guide, you will set up a JWT-based modern authentication system in Express.js projects.
Access–refresh token structure, middleware usage and role-based authorization are discussed.
Technical Summary
- Subject: Express.js JWT Authentication
- Purpose: Session-free, scalable API security
- Approach: Access token + Refresh token
- Scope: Middleware, RBAC, cookie security
Preliminary Preparations
- A development environment with Node.js installed
- Basic JavaScript knowledge
- Familiarity with REST API logic
- Terminal usage
What is JWT?
JWT (JSON Web Token) is a signed JSON data structure.
Provides authentication without storing the session on the server side.
JWT consists of three parts:
- Header -Payload Signature
Payload is not encrypted, only encoded.
Why is JWT Preferred?
- REST API authentication
- Microservice architectures
- Horizontally scaling systems
- Multiple service access with a single session
Each server can verify the token independently.
1. Project Setup
mkdir genixnode-jwt-auth
cd genixnode-jwt-auth
npm init -y
- This command creates the project configuration.
"type": "module"
- This setting enables the use of ES Modules.
npm install express dotenv jsonwebtoken cookie-parser
- These packages are required for JWT and cookie management.
2. Basic Express Server Structure
import express from 'express';
import dotenv from 'dotenv';
import cookieParser from 'cookie-parser';
dotenv.config();
const app = express();
app.use(express.json());
app.use(cookieParser());
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Sunucu ${PORT} portunda çalışıyor`);
});
- This build starts an Express server with JSON and cookie support.
3. JWT Secret Configuration
ACCESS_TOKEN_SECRET=uzun_ve_rastgele_bir_metin
REFRESH_TOKEN_SECRET=baska_uzun_ve_gizli_bir_metin
Secret değerleri asla koda gömülmemelidir.
4. Access Token Generation
import jwt from 'jsonwebtoken';
function accessTokenUret(kullanici) {
return jwt.sign(
{ id: kullanici.id, rol: kullanici.rol },
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: '15m' }
);
}
- This function generates a short-lived access token.
5. JWT Authentication Middleware
export function tokenDogrula(req, res, next) {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ mesaj: 'Token bulunamadı' });
}
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (hata, veri) => {
if (hata) {
return res.status(403).json({ mesaj: 'Token geçersiz veya süresi dolmuş' });
}
req.user = veri;
next();
});
}
- This middleware authenticates for protected routes.
6. Login and Refresh Token Strategy
| Token | Duration | Purpose |
|---|---|---|
| Access Token | ~15 minutes | Provides API access, usually for short-term use |
| Refresh Token | ~7 days | Used to obtain a new access token, for long-term use |
- Refresh token must be stored in HttpOnly cookie.
Login Example
app.post('/giris', (req, res) => {
const kullanici = { id: 1, rol: 'editor' };
const accessToken = accessTokenUret(kullanici);
const refreshToken = jwt.sign(
kullanici,
process.env.REFRESH_TOKEN_SECRET
);
res.cookie('jwt', refreshToken, {
httpOnly: true,
secure: true,
sameSite: 'Strict'
});
res.json({ accessToken });
});
- This structure seriously reduces the risk of XSS.
7. Role Based Authorization (RBAC)
function sadeceAdmin(req, res, next) {
if (req.user.rol !== 'admin') {
return res.status(403).json({ mesaj: 'Yetkiniz yok' });
}
next();
}
- This middleware protects admin routes.
app.delete(
'/kullanici/:id',
tokenDogrula,
sadeceAdmin,
(req, res) => {
res.send('Kullanıcı silindi');
}
);
Security Best Practices
1. Do not store JWT in localStorage
2. Use HttpOnly cookie for refresh token
3. Let the access token be short-lived
4. Make the exp field mandatory
5. Secrets must be environment variables
Frequently Asked Questions
1. How to logout with JWT? Refresh cookie is cleared, access token is deleted on the client.
2. Is JWT payload safe? Readable. Confidential data should not be added.
3. If refresh token is stolen? Token rotation or token version must be applied.
4. HS256 or RS256? HS256 is sufficient for a single server. RS256 is recommended in distributed systems.
Result
JWT provides modern and scalable authentication in Express.js projects. When designed correctly, it is safe, easy to maintain and high-performance. You can safely use this architecture on the GenixNode infrastructure.

