In this tutorial, our goal is to understand the concepts of Authentication and Authorization, and to implement them in a web application.
You will learn how to authenticate users, manage sessions, restrict access to certain parts of your application based on user roles, and handle user permissions.
Prerequisites:
- Basic knowledge of a server-side language (This tutorial uses Node.js)
- Familiarity with Express.js
- Understanding of HTTP and RESTful APIs.
Authentication is the process of verifying who the user is, while Authorization is the process of verifying what they have access to.
We will create an Express application and use JWT (JSON Web Tokens) for authentication.
To authenticate a user, we first need them to register. We'll use bcrypt to hash the password.
const express = require('express');
const bcrypt = require('bcrypt');
let users = [];
const app = express();
app.use(express.json());
app.post('/register', async (req, res) => {
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const user = { name: req.body.name, password: hashedPassword };
users.push(user);
res.status(201).send();
} catch {
res.status(500).send();
}
});
In this code, we're creating a new user with a hashed password and storing it in the users
array.
Now, let's authenticate users during login and issue a JWT.
const jwt = require('jsonwebtoken');
let refreshTokens = [];
app.post('/login', async (req, res) => {
const user = users.find(user => user.name == req.body.name)
if (user == null) {
return res.status(400).send('Cannot find user')
}
try {
if(await bcrypt.compare(req.body.password, user.password)) {
const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET);
const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET);
refreshTokens.push(refreshToken);
res.json({ accessToken: accessToken, refreshToken: refreshToken });
} else {
res.send('Not Allowed');
}
} catch {
res.status(500).send();
}
});
Here, if the user is found and the password matches, we're creating an access token and a refresh token using JWT and sending them to the client.
In this tutorial, we've learned how to handle user registration and login, hash passwords, generate and manage JWTs. For authorization, you can use the jsonwebtoken
library's verify
method to ensure only authenticated users can access certain routes.
Next steps include learning how to handle password resets, multi-factor authentication, and OAuth.
Some additional resources:
- jsonwebtoken GitHub
- bcrypt GitHub
Solutions:
app.delete('/logout', (req, res) => {
refreshTokens = refreshTokens.filter(token => token !== req.body.token);
res.sendStatus(204);
});
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401);
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
role
field to your users and checking that role in your protected routes.Keep practicing and building different features to get a solid understanding of Authentication and Authorization.