As a backend engineer, you get a lot of control over how people are authenticated and their state is stored.
Back in the day, it was common to see "stateful" architecture, where all authentication data was stored in a database and the user got a state ID that connected the user to that specific entry in the DB.
Now, it was fine when the userbase was small, but as more users used your webapp, the overhead for querying the database got bigger.
In the image, the user performs an action that requires authorization (eg. post a blog). A sessionid is sent to the server (through cookies or headers) which is verified by the server by querying the database. If sessionid is valid, ie. it is present in the database, then the action is allowed to be performed.
This is simply too much work for something so trivial
Let me introduce you to a method of auth that doesn't need session data to be stored on the server, thus reducing overhead, improving user experience and speed.
The basic idea of JWT is that instead of storing sessionids on the user, we store a JSON object in base64 format.
This is the typical flow for JWT based auth:
Do you see how much simpler it got? We eliminate the need to query our DB every time a user does something that needs auth. Fantastic!
(You can learn about JWT in depth here)
Start by creating an npm package
$ npm init -y
Then install JWT, Expressjs and cookie-parser
$ npm install express jsonwebtoken cookie-parser
Then put the following into main.js:
'use strict'
const express = require("express");
const app = express();
const cp = require("cookie-parser");
const jwt = require("jsonwebtoken");
app.use(cp());
app.get("/login", (req, res)=>{
const token = jwt.sign({email: "[email protected]"}, "thiskeyisverysecret", {expiresIn: "7d"}); // Generate a jwt that will expire in 7 days
res.cookie("token", token, {httpOnly: true, maxAge: 60 * 60 * 24 * 7}); // Create an HttpOnly cookie that is valid for 7 days
res.send("You are now logged in!");
});
app.get("/protected", (req, res)=>{
try {
const user = jwt.verify(req.cookies["token"], "thiskeyisverysecret", {algorithms: ["HS256"]}); // Verify the cookie called "token" against secret key
res.send("Action performed!");
} catch(err) {
// An error is thrown if the JWT is invalid or has expired
res.send("You must be logged in to perform this action");
}
});
app.listen(8080);
console.log("Server started");
Let's understand what's going on here.
GETs on /login the server generates a JWT with the user's email and signs it with the secret key. This token is sent to the user as an HttpOnly cookieGETs on a route that needs authorization, (here /protected), then the JWT present in the token cookie is verified against secret key. If the token is valid, the server allows the action.Thanks for reading till the end. Here are some additional resources that may help you:
JSON Web Tokens Website
Advanced JWT use