Express: Result Page
Design a protected /result route that only logged-in students can access.
Use session middleware to verify if the student is logged in before allowing access to the route.
If the session is valid, the route should display the message: "Hi
[name]
, your results are available!".If the user is not logged in, it should return an access denied message: "Access denied: Please login to view results."
Add a /logout route that properly destroys the session and clears the login cookie.
app.js
import express from 'express';
import session from 'express-session';
import cookieParser from 'cookie-parser';
// --- App Initialization ---
const app = express();
const PORT = 3001;
// --- In-Memory Data (for demonstration purposes) ---
const users = [
{ id: 1, username: 'student1', name: 'Alice', password: 'password1' },
{ id: 2, username: 'student2', name: 'Bob', password: 'password2' }
];
// --- Middleware ---
app.use(express.json());
app.use(cookieParser());
// Configure session management
app.use(session({
secret: 'a-very-secret-key-for-students',
resave: false,
saveUninitialized: false,
cookie: { secure: false}
}));
// --- API Routes ---
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);
if (!user) {
return res.status(401).json({ error: 'Invalid username or password.' });
}
// Store the user's ID in the session
req.session.userId = user.id;
res.cookie( 'studentPortalAccess',
user.id,
{ maxAge: 3 * 60 * 1000 });
res.json({ message: `Welcome, ${user.name}!` });
});
// Authentication Middleware
const authenticate = (req, res, next) => {
if (!req.session.userId) {
return res.status(401).json({ error: 'Access denied. Please log in.' });
}
next();
};
app.get('/result', authenticate, (req, res) => {
// `authenticate` middleware has already verified the session.
const user = users.find(u => u.id === req.session.userId);
res.send(`Hi ${user.name}, your results are available!`);
});
app.post('/logout', (req, res) => {
req.session.destroy(err => {
if (err) {
return res.status(500).json({ error: 'Logout failed. Please try again.' });
}
// The default session cookie is named 'connect.sid'
res.clearCookie('studentPortalAccess');
res.json({ message: 'Successfully logged out.' });
});
});
// --- Start Server ---
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
All routes with ejs
Updated Express.js application with the protected /result route and a functional /logout route.
The key changes are the new authMiddleware
function to protect routes and the addition of the /result
and /logout
endpoints.
app.js
import express from 'express';
import session from 'express-session';
import cookieParser from 'cookie-parser';
import path from 'path';
import { fileURLToPath } from 'url';
const app = express();
const PORT = 3000;
// Needed for __dirname in ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// --- Middleware Setup ---
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(session({
secret: 'a_secret_key_to_sign_the_cookie',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
// Set EJS as the view engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// In-memory student database
const students = [];
// Custom middleware to check for authenticated session
const authMiddleware = (req, res, next) => {
if (req.session && req.session.student) {
return next(); // Session is valid, proceed to the route
}
// No valid session, deny access
res.status(403).send('Access denied: Please login to view results.');
};
// --- Routes ---
// Render registration page
app.get('/register', (req, res) => {
res.render('register');
});
// Handle registration logic
app.post('/register', (req, res) => {
const { rollNo, name, password } = req.body;
students.push({ rollNo, name, password });
console.log('Students:', students);
res.redirect('/login');
});
// Render login page
app.get('/login', (req, res) => {
res.render('login');
});
// Handle login logic
app.post('/login', (req, res) => {
const { rollNo, password } = req.body;
const student = students.find(s => s.rollNo === rollNo && s.password === password);
if (student) {
req.session.student = { rollNo: student.rollNo, name: student.name };
res.cookie('studentPortalAccess', student.rollNo, { maxAge: 3 * 60 * 1000 });
res.redirect('/dashboard');
} else {
res.send('Invalid roll number or password.');
}
});
// Render dashboard (protected)
app.get('/dashboard', authMiddleware, (req, res) => {
res.render('dashboard', { student: req.session.student });
});
// NEW: Protected result route
app.get('/result', authMiddleware, (req, res) => {
const studentName = req.session.student.name;
res.status(200).send(`Hi ${studentName}, your results are available!`);
});
// NEW: Logout route
app.get('/logout', (req, res) => {
req.session.destroy(err => {
if (err) {
// Handle error case, e.g., redirect to dashboard
return res.redirect('/dashboard');
}
// Clear the cookie and redirect to login
res.clearCookie('studentPortalAccess');
res.redirect('/login');
});
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}/register`);
});
EJS Files
The register.ejs
and login.ejs
files remain the same. The dashboard.ejs
is updated to include a link to the new /result route.
views/dashboard.ejs
(Updated)
<!DOCTYPE html>
<html lang="en">
<head><title>Dashboard</title></head>
<body>
<h1>Welcome to the Student Portal, <%= student.name %>!</h1>
<p>Your Roll Number is: <%= student.rollNo %></p>
<p><a href="/result">View Your Results</a></p>
<a href="/logout">Logout</a>
</body>
</html>
Run and Test
npm init -y
npm install express express-session cookie-parser ejs
Then, ensure your package.json
includes "type": "module"
.
node app.js
Test without Logging In: Open a new private/incognito browser window and navigate directly to
http://localhost:3000/result
. You will see the "Access denied" message.Log In: Navigate to
http://localhost:3000/login
and log in with a registered student's credentials. You will be redirected to the dashboard.Access Results: From the dashboard, click the "View Your Results" link. You will be taken to the /result page and see the personalized welcome message.
Log Out: From the dashboard, click the "Logout" link. You will be redirected back to the login page.
Verify Logout: Try to navigate back to
http://localhost:3000/dashboard
orhttp://localhost:3000/result
. You will be blocked and see the "Access denied" message again, confirming the session was successfully destroyed.