CamKode

Basic JWT (JSON Web Tokens) with Node.js and TypeScript

Avatar of Kosal Ang

Kosal Ang

Thu Jan 04 2024

Basic JWT (JSON Web Tokens) with Node.js and TypeScript

JSON Web Tokens (JWTs) are a way to securely transmit information between parties as a JSON object. In TypeScript, you can work with JWTs by using libraries like jsonwebtoken for generating, signing, and verifying tokens.

Below are the steps to work with jsonwebtoken using TypeScript:

Step 1: Install Required Packages

Install Express and jsonwebtoken:

1npm install express jsonwebtoken
2

Step 2: Set Up Dependencies and Initialize Express Server

1import express, { Request, Response } from 'express'
2import jwt from 'jsonwebtoken'
3
4const app = express()
5const PORT = 3000
6
7app.use(express.json())
8

This step imports necessary modules (express for server creation, jsonwebtoken for token handling), initializes the Express app, and sets the server port to 3000. It also enables the app to parse JSON requests.

Step 3: Define JWT Secret Key and Simulated User Data

1const JWT_SECRET = 'your_jwt_secret'
2
3const users = [
4  {
5    id: 1,
6    username: 'user1',
7    password: 'password1',
8  },
9  {
10    id: 2,
11    username: 'user2',
12    password: 'password2',
13  },
14]
15

This step establishes a secret key for signing JWT tokens and defines a simulated array of user objects with IDs, usernames, and passwords.

Step 4: Create Function to Generate JWT Tokens

1const generateToken = (userId: number): string => {
2  return jwt.sign({ userId }, JWT_SECRET, { expiresIn: '1h' }) // Token expires in 1 hour
3}
4

This function generateToken accepts a userId and generates a JWT token using the jsonwebtoken package. It signs the token with the secret key and sets it to expire in 1 hour.

Step 5: Create Login Route to Generate JWT Token

1app.post('/login', (req: Request, res: Response) => {
2  const { username, password } = req.body
3
4  const user = users.find((u) => u.username === username && u.password === password)
5
6  if (!user) {
7    return res.status(401).json({ message: 'Invalid credentials' })
8  }
9
10  const token = generateToken(user.id)
11  res.json({ token })
12})
13

This route /login listens for POST requests. It receives username and password in the request body, checks if the provided credentials match any user in the simulated users array, and generates a JWT token if the credentials are valid.

Step 6: Create Protected Route Requiring a Valid JWT Token

1app.get('/protected', (req: Request, res: Response) => {
2  const token = req.headers.authorization?.split(' ')[1]
3
4  if (!token) {
5    return res.status(401).json({ message: 'Unauthorized: No token provided' })
6  }
7
8  jwt.verify(token, JWT_SECRET, (err, decoded) => {
9    if (err) {
10      return res.status(401).json({ message: 'Unauthorized: Invalid token' })
11    }
12
13    res.json({ message: 'Welcome to the protected route' })
14  })
15})
16

This route /protected listens for GET requests. It expects a valid JWT token in the Authorization header. It verifies the token's authenticity using jwt.verify with the secret key. If the token is valid, it responds with a welcome message; otherwise, it returns an unauthorized error.

Step 7: Start the Express Server

1app.listen(PORT, () => {
2  console.log(`Server running on port ${PORT}`)
3})
4

This code starts the Express server, listening on port 3000, and logs a message confirming the server's start.

Full code example

1import express, { Request, Response } from 'express'
2import jwt from 'jsonwebtoken'
3
4const app = express()
5const PORT = 3000
6
7app.use(express.json())
8
9// Secret key for signing the JWT tokens
10const JWT_SECRET = 'your_jwt_secret'
11
12// Simulated user data (This might be fetched from a database)
13const users = [
14  {
15    id: 1,
16    username: 'user1',
17    password: 'password1',
18  },
19  {
20    id: 2,
21    username: 'user2',
22    password: 'password2',
23  },
24]
25
26// Generate JWT token
27const generateToken = (userId: number): string => {
28  return jwt.sign({ userId }, JWT_SECRET, { expiresIn: '1h' }) // Token expires in 1 hour
29}
30
31// Simulated login route to generate and return a JWT token
32app.post('/login', (req: Request, res: Response) => {
33  const { username, password } = req.body
34
35  // Check if user exists and credentials match (This might involve DB queries in a real app)
36  const user = users.find((u) => u.username === username && u.password === password)
37
38  if (!user) {
39    return res.status(401).json({ message: 'Invalid credentials' })
40  }
41
42  const token = generateToken(user.id)
43  res.json({ token })
44})
45
46// Protected route that requires a valid JWT token
47app.get('/protected', (req: Request, res: Response) => {
48  const token = req.headers.authorization?.split(' ')[1] // Get token from Authorization header
49
50  if (!token) {
51    return res.status(401).json({ message: 'Unauthorized: No token provided' })
52  }
53
54  jwt.verify(token, JWT_SECRET, (err, decoded) => {
55    if (err) {
56      return res.status(401).json({ message: 'Unauthorized: Invalid token' })
57    }
58
59    // Token is valid, you can perform actions for the authenticated user here
60    res.json({ message: 'Welcome to the protected route' })
61  })
62})
63
64app.listen(PORT, () => {
65  console.log(`Server running on port ${PORT}`)
66})
67

Test the Endpoints

  • Login Endpoint: Send a POST request to /login with the username and password in the request body. You will receive a JWT token in the response.

  • Protected Endpoint: Access the protected route /protected by sending a GET request with the received JWT token in the Authorization header. Ensure you set the Authorization header as Bearer <your_token>. ess the protected route /protected by sending a GET request with the received JWT token in the Authorization header. Ensure you set the Authorization header as Bearer <your_token>.

Related Posts

How to Merge Enumerations in TypeScript

How to Merge Enumerations in TypeScript

There are scenarios where you might want to merge multiple enums into one, combining their respective values into a single type

How to install Tailwind CSS in Next.js

How to install Tailwind CSS in Next.js

TailwindCSS is a popular CSS framework that can help you create nice user interfaces quickly with pre-made CSS classes.

Implementing JWT Authentication in Flask

Implementing JWT Authentication in Flask

Learn how to implement JWT (JSON Web Token) authentication in Flask using Flask-JWT-Extended. This tutorial guides you through creating user authentication endpoints for registration, login, and logout, as well as protecting routes with JWT tokens for secure access control.

Basic Setup Your PIXI.js App with Typescript and Webpack

Basic Setup Your PIXI.js App with Typescript and Webpack

Basic Setting up your first PIXI.js Typescript and Webpack

© 2024 CamKode. All rights reserved

FacebookTwitterYouTube