0% found this document useful (0 votes)
2 views6 pages

Lab11 - Authentication and Authorization

The document outlines a lab focused on implementing secure user authentication using JSON Web Tokens (JWT) in an Express.js application, with user data stored in MongoDB. Students will learn password hashing with bcrypt, token generation, and route protection through middleware. The lab includes project setup, user model creation, registration and login routes, and the use of protected routes, culminating in testing with Postman.

Uploaded by

amir.raza537918
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views6 pages

Lab11 - Authentication and Authorization

The document outlines a lab focused on implementing secure user authentication using JSON Web Tokens (JWT) in an Express.js application, with user data stored in MongoDB. Students will learn password hashing with bcrypt, token generation, and route protection through middleware. The lab includes project setup, user model creation, registration and login routes, and the use of protected routes, culminating in testing with Postman.

Uploaded by

amir.raza537918
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

Lab 11 – Authentication and Authorization

Objective:
To implement secure user authentication using JSON Web Tokens (JWT) in an Express.js
app. The user data will be stored in MongoDB using Mongoose. Students will learn about
password hashing, token generation, and protecting routes.

Activity Outcomes:

By completing this lab, students will:

 Understand the structure of secure user login systems


 Be able to hash passwords using bcrypt
 Generate and verify JWTs
 Protect backend routes using authentication middleware

1) Useful Concepts
Hashing with bcrypt
Passwords should never be stored as plain text. If your database gets leaked, unhashed passwords
would expose users to identity theft or account compromise. bcrypt is a password-hashing library
designed to securely store passwords. It's widely used in web applications, including Express.js, to
protect user passwords from being stored in plain text.
bcrypt adds multiple layers of protection:
 Hashing – Converts the password into a fixed-length string.
 Salting – Adds random data to the password before hashing to prevent common attacks like
rainbow table attacks.
 Adaptive – Allows the cost factor (work factor) to be increased over time to make brute-force
attacks more difficult.

const bcrypt = require('bcryptjs');

const password = "userpassword123";

// Hash the password


const hashedPassword = await bcrypt.hash(password, 10); // 10 = salt rounds

// Later, verify login


const isValid = await bcrypt.compare("userpassword123", hashedPassword);

JSON Web Token (JWT)


JSON Web Token (JWT) is a compact, URL-safe token format used to securely transmit
information between two parties — usually the client and the server — as a JSON object.
It’s commonly used in authentication and authorization processes in web applications, especially in
modern RESTful APIs and single-page applications.

What is JWT used for?


 Authentication: After a user logs in successfully, the server creates a JWT and sends it to the
client. The client then includes this token in future requests to authenticate itself.
 Authorization: JWT can include user roles or permissions, allowing access to specific
resources.

A JWT consists of three parts, separated by dots (.):

header.payload.signature

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ.
sflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1. Header:
Specifies the type of token and the algorithm used to sign it.
{
"alg": "HS256",
"typ": "JWT"
}

2. Payload:
Contains the claims — information like user ID, email, role, etc.

{
"userId": "123456",
"role": "admin",
"iat": 1715589993,
"exp": 1715593593
}

3. Signature:
Used to verify the token’s authenticity and integrity.

HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)

How JWT works (Flow)


1. User logs in with email/password.
2. Server verifies credentials and creates a JWT.
3. JWT is sent back to the client and stored (typically in localStorage or cookies).
4. For every protected request, the client sends the token in the Authorization header:

Authorization: Bearer <token>

5. Server validates the token and grants or denies access.

Pros of JWT:
 Stateless: No need to store session data on the server.
 Scalable: Great for microservices and APIs.
 Portable: Easily passed around via headers, cookies, or URLs.

2) Solved Lab Activites


Sr.No Allocated Time Level of Complexity CLO Mapping
1 10 Low CLO-5
2 10 Low CLO-5
3 10 Medium CLO-5
4 10 Medium CLO-5
5 10 Medium CLO-5
6 10 Medium CLO-5

Activity 1: Setup Project and Install Packages


Task 1: Initialize Project and Install Packages
Instructions:
1. Create a new folder and initialize a Node project.
2. Install required packages.

npm init -y
npm install express mongoose bcrypt jsonwebtoken dotenv

Activity 2: Set Up Mongoose and Create User Model

models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const UserSchema = new mongoose.Schema({


username: { type: String, required: true, unique: true },
password: { type: String, required: true }
});

UserSchema.pre('save', async function (next) {


if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});

module.exports = mongoose.model('User', UserSchema);

Activity 3: Create Registration and Login Routes

routes/auth.js

const express = require('express');

const jwt = require('jsonwebtoken');


const bcrypt = require('bcrypt');
const User = require('../models/User');
const router = express.Router();

// Register Route
router.post('/register', async (req, res) => {
try {
const { username, password } = req.body;
const exists = await User.findOne({ username });
if (exists) return res.status(400).json({ message: 'User already exists' });

const user = new User({ username, password });


await user.save();
res.status(201).json({ message: 'User registered' });
} catch (err) {
res.status(500).json({ message: 'Error registering user' });
}
});
// Login Route
router.post('/login', async (req, res) => {
try {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (!user) return res.status(400).json({ message: 'User not found' });

const match = await bcrypt.compare(password, user.password);


if (!match) return res.status(401).json({ message: 'Invalid password' });

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h'


});
res.json({ token });
} catch (err) {
res.status(500).json({ message: 'Error logging in' });
}
});

module.exports = router;

Activity 4: Create Middleware to Protect Routes

middleware/auth.js

const jwt = require('jsonwebtoken');

const auth = (req, res, next) => {


const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'No token provided' });

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
res.status(403).json({ message: 'Invalid token' });
}
};

module.exports = auth;

Activity 5: Use Protected Route

routes/protected.js

const express = require('express');


const auth = require('../middleware/auth');
const router = express.Router();
router.get('/dashboard', auth, (req, res) => {
res.json({ message: `Welcome user ${req.user.id}` });
});

module.exports = router;

Activity 6: Main Server File

server.js

require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const authRoutes = require('./routes/auth');
const protectedRoutes = require('./routes/protected');

const app = express();


app.use(express.json());

mongoose.connect(process.env.MONGO_URI, () => {
console.log('Connected to MongoDB');
});

app.use('/auth', authRoutes);
app.use('/api', protectedRoutes);

app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});

Activity 7: .env File

MONGO_URI=mongodb://localhost:27017/jwt-lab
JWT_SECRET=supersecretkey

Test with Postman

1. POST /auth/register → with username and password


2. POST /auth/login → returns a token
3. GET /api/dashboard → with Authorization: Bearer <token>

3) Graded Lab Tasks

You might also like