How to Use JSON Web Tokens (JWTs) in Express.js
In this tutorial, you'll learn how to set up JWTs (JSON Web Tokens) in a Node.js environment with Express. You'll learn how to install the dependencies required for the JWTs to function correctly and work with a few code examples.
What Are JWTs?
JWTs, or JSON Web Tokens, are an open standard (RFC 7519) for securely transferring information between parties. They contain authentication or authorization data to securely gain access to server-side resources.
JWTs can be transmitted as URL parameters, POST parameters, or via an HTTP header. They're encrypted with a token secret using the HMAC algorithm or a public/private key pair using RSA or ECDSA encryption and validated using its signature.
Install & Intialize the JSON Web Token Library
First, you'll need to install the JSON Web Token library on your machine:
npm install jsonwebtoken
Next, import the library into your code:
const jwt = require("jsonwebtoken");
Generating Tokens
To generate a JWT access token, we'll need three pieces of information:
Token secret
string - a random string used to encrypt and decrypt data you pass in.Data
string - either a simple string or a JSON string. This data will be hashed in your token.Token expiration time
string - the time before the JWT becomes invalid. For example, passing in a value of 300s means the token will expire in 300 seconds or five minutes.
Creating A Token Secret
To generate a random token secret string, you can use Node.js' built-in Crypto library:
const crypto = require ("crypto");
const secret = crypto.randomBytes(64).toString("hex");
console.log(secret);
// c0a971ec43d510492a2e9262edd21e019c426490d185de47b2a22beae8e166fabf9160df28030c7c84d2a021d18b57bb4525a2dbcbb88fb7d5a8003314e01029
Now you can store the token secret in your project's environment .env
file:
TOKEN_SECRET=c0a971ec43d510492a2e9262edd21e019c426490d185de47b2a22beae8e166fabf9160df28030c7c84d2a021d18b57bb4525a2dbcbb88fb7d5a8003314e01029
Use the following variable to access your token secret from within your application:
process.env.TOKEN_SECRET
Make sure to keep your token secret safe, hidden, and complex enough so that it can't be cracked. If you expose your token secret or make it too easy to figure out, you'll make it much easier for unauthorized users to gain access to your resources!
Signing Tokens
A signature is used to verify that the sender of the JWT is who they say they are. This can be done with the jwt.sign()
method:
function generateAccessToken(my_string) {
return jwt.sign(my_string, process.env.TOKEN_SECRET, {expiresIn: "300s"});
}
Which can then be called in an API request:
app.post("/api/someAction", (req, res) => {
const token = generateAccessToken({my_string: req.body.my_string});
res.json(token);
});
Authenticating Tokens
Now, we'll create a JWT authentication system in Express.js using middleware functionality, creating functions that accept parameters (req, res, next)
to handle the requests.
req
- the sent request (GET, POST, DELETE, etc.)res
- the response sent back to the user (200 OK, 404 Not Found, etc.)next
- executes code after the middleware function completes processing.
Here's an example of a middleware function for token authentication. This function grabs the JWT access token from the request header:
function authenticateToken(req, res, next) {
const header = req.headers["authorization"];
const token = header && header.split(" ")[1];
if (token == null) {
return res.sendStatus(404);
}
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET as string, (err: any, user: any) => {
if (err) {
return res.sendStatus(403);
}
req.user = user;
next();
});
}
This middleware function searches for a variable named Authorization
in the header, splits the string into two by removing the first word before the space, Bearer, and assigns the value to a variable named token
. If the token is not found or parsed incorrectly, a 404 error is returned to the user.
From there, we validate our token string against our ACCESS_TOKEN_SECRET
environment variable and assign it to the req.user
variable if validation is successful. Otherwise, a 403 forbidden error is returned to the user, meaning the user cannot gain further access until a valid token is provided.
An example HTTP request could look something like this:
GET https://domain.com:3000/api/userInfo
Authorization: Bearer JWT_ACCESS_TOKEN
An example of a request within Node.js using the middleware function we created could look like this:
app.get("/api/userInfo", authenticationToken, (req, res) => {
// executes after the authenticationToken() function is called
});
Client-Side Token Storage
You can store your access token client-side using one of two methods.
localStorage
const token = await res.json();
localStorage.setItem("token", token);
Cookies
const token = await res.json();
document.cookie = "token=${token}";
Conclusion
In this tutorial, you learned how to generate, sign, and handle JSON Web Tokens (JWTs) with Node.js and Express, and how to assign your generated token to client-side storage.