JWT auth without the confusion
JWT auth without the confusion JWTs are everywhere, but they're often misunderstood. Let's strip away the jargon and see what they actually are, how they work, and how to use them safely in your apps. What is a JWT? A JWT (JSON Web Token) is just a string with three parts separated by dots: header.payload.signature Header : contains the algorithm and token type. Payload : contains claims (data…
JSON Web Tokens (JWTs) are widely used for authentication in web applications, but they are often misunderstood. In this article, we'll break down what JWTs are, how they function, and how to implement them securely in your applications.
A JWT is a string composed of three segments, separated by dots: the header, the payload, and the signature. The header indicates the algorithm and token type, the payload contains claims such as user ID, expiration time, etc., and the signature is used to verify that the token hasn't been altered. All segments are base64url encoded.
The process of authentication using JWTs involves a user logging in with credentials, the server verifying these credentials to create a JWT with user information, sending the token back to the client, and the client storing this token (usually in memory or localStorage) to include it in the Authorization header of subsequent requests. The server then verifies the token's signature and expiration before trusting the claims.
However, there are common pitfalls to avoid:
1. Storing tokens in localStorage: Since localStorage is accessible to any JavaScript running on a page, it's vulnerable to Cross-Site Scripting (XSS) attacks. If an attacker injects malicious script, they could steal the token. Instead, use HttpOnly cookies, which are not accessible to JavaScript, but require CSRF protection.
2. Not checking token expiration: Always verify the exp claim in the payload. Use a library that validates this automatically.
3. Including sensitive data in the payload: While the payload is base64 encoded, it's not encrypted. Avoid storing sensitive information like passwords or credit card details in the payload.
4. Using a weak secret: For symmetric encryption (HS256), the secret must be long and random. In production, asymmetric encryption (RS256) with a private/public key pair is recommended.
Here's a minimal example of JWT authentication in Node.js using Express:
```javascript
const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();
const SECRET = process.env.JWT_SECRET || 'change-me';
app.use(express.json());
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (username === 'admin' && password === 'secret') {
const token = jwt.sign({ sub: username }, SECRET, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});
function authMiddleware(req, res, next) {
const header = req.headers.authorization;
if (!header || !header.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing token' });
}
const token = header.slice(7);
try {
const payload = jwt.verify(token, SECRET);
req.user = payload;
next();
} catch (err) {
res.status(401).json({ error: 'Invalid token' });
}
}
app.get('/protected', authMiddleware, (req, res) => {
res.json({ message: 'You are authenticated', user: req.user });
});
app.listen(3000);
```
When choosing between JWT and sessions, JWT is advantageous for stateless APIs, especially microservices, and for mobile apps where cookies pose challenges. However, sessions might be preferable if you need to revoke tokens instantly or manage a single-server application. For production, always use HTTPS, set short expiration times, validate the aud and iss claims, and keep the secret or private key out of your source code.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — it may contain errors, so check the original before relying on it.