done with middleware auth check

This commit is contained in:
Kfir Dayan 2023-06-09 18:39:20 +03:00
parent 92b65e02d0
commit 642600db3d
8 changed files with 102 additions and 51 deletions

31
package-lock.json generated
View file

@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.6",
"dotenv": "^16.1.4", "dotenv": "^16.1.4",
"express": "^4.18.2", "express": "^4.18.2",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",
@ -18,6 +19,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/bcryptjs": "^2.4.2", "@types/bcryptjs": "^2.4.2",
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2" "@types/jsonwebtoken": "^9.0.2"
} }
@ -47,6 +49,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/cookie-parser": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz",
"integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==",
"dev": true,
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.17", "version": "4.17.17",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
@ -242,6 +253,26 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": { "node_modules/cookie-signature": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",

View file

@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.6",
"dotenv": "^16.1.4", "dotenv": "^16.1.4",
"express": "^4.18.2", "express": "^4.18.2",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",
@ -18,6 +19,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/bcryptjs": "^2.4.2", "@types/bcryptjs": "^2.4.2",
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2" "@types/jsonwebtoken": "^9.0.2"
} }

View file

@ -1,7 +1,10 @@
import { Request, Response } from 'express'; import express, { Request, Response } from 'express';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { User, IUser } from '../models/User'; import { User, IUser } from '../models/User';
import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth';
const app = express();
export async function createUser(req: Request, res: Response) { export async function createUser(req: Request, res: Response) {
try { try {
@ -33,18 +36,35 @@ export async function login(req: Request, res: Response) {
} }
// Compare the provided password with the stored password // Compare the provided password with the stored password
const isPasswordValid = await bcrypt.compare(password, user.password); const isPasswordCorrect = await bcrypt.compare(password, user.password);
if (!isPasswordValid) { if (!isPasswordCorrect) {
return res.status(401).json({ error: 'Invalid email or password' }); return res.status(401).json({ error: 'Invalid email or password' });
} }
const payload = {
userId: user._id
}
// Generate a JWT // Generate a JWT
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET as string); const token = jwt.sign(payload, process.env.JWT_SECRET as string, { expiresIn: '1d' });
setJwtCookie(res, token);
// Send the JWT as the response // Send the JWT as the response
res.json({ token }); res.status(200).json({
username: user.firstName
});
} catch (error) { } catch (error) {
console.error('Error during login:', error); console.error('Error during login:', error);
res.status(500).json({ error: 'An error occurred during login' }); res.status(500).json({ error: 'An error occurred during login' });
} }
}
export async function logout(req: Request, res: Response) {
try {
clearJwtCookie(res);
res.status(200).json({ message: 'Logout successful' });
} catch (error) {
console.error('Error during logout:', error);
res.status(500).json({ error: 'An error occurred during logout' });
}
} }

View file

@ -1,10 +1,9 @@
import express from 'express'; import express from 'express';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import cookieParser from 'cookie-parser';
import userRouter from './routes/user'; import userRouter from './routes/user';
import ProductrRouter from './routes/product'; import productRouter from './routes/product';
import { authenticateToken } from './middlewares/authMiddleware';
const env = require('dotenv').config().parsed; const env = require('dotenv').config().parsed;
@ -12,7 +11,7 @@ const app = express();
const PORT = 3000; const PORT = 3000;
app.use(express.json()); app.use(express.json());
app.use(authenticateToken); app.use(cookieParser())
// Connect to MongoDB using Mongoose // Connect to MongoDB using Mongoose
@ -28,7 +27,7 @@ db.once('open', () => {
// Routes // Routes
app.use('/users', userRouter); app.use('/users', userRouter);
app.use('/products', ProductrRouter); app.use('/products', productRouter);
// Start server // Start server
app.listen(PORT, () => { app.listen(PORT, () => {

View file

@ -1,37 +0,0 @@
import { Request, Response, NextFunction } from 'express';
import jwt, { JwtPayload } from 'jsonwebtoken';
interface AuthenticatedRequest extends Request {
user?: JwtPayload | string;
}
const exceptionRoutes: string[] = ['/users/login', '/users'];
// Middleware function to authenticate requests
export function authenticateToken(req: AuthenticatedRequest, res: Response, next: NextFunction) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if(token) {
console.log('token', token);
}
if (!token && exceptionRoutes.includes(req.route)) {
return res.sendStatus(401); // Unauthorized
}
if (!exceptionRoutes.includes(req.route)) {
// Skip authentication for exception routes
return next();
}
jwt.verify(token as string, process.env.JWT_SECRET as string, (err, user) => {
if (err) {
return res.sendStatus(403); // Forbidden
}
// Store the authenticated user in the request object
req.user = user as JwtPayload | string;
next();
});
}

View file

@ -0,0 +1,34 @@
import express, { Request, Response, NextFunction } from 'express';
import jwt, { JwtPayload } from 'jsonwebtoken';
import cookieParser from 'cookie-parser';
interface AuthenticatedRequest extends Request {
userId?: string;
}
// Middleware function to authenticate requests
export function authenticateToken(req: AuthenticatedRequest, res: Response, next: NextFunction) {
const token = req.cookies.access_token;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
const user_id = jwt.verify(token, process.env.JWT_SECRET as string, (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'In Valid Token' });
}
req.userId = decoded.userId;
next();
});
}
// Set JWT as cookie in the response
export function setJwtCookie(res: Response, token: string) {
res.cookie('access_token', token, { httpOnly: true });
}
// Clear JWT cookie in the response
export function clearJwtCookie(res: Response) {
res.clearCookie('access_token');
}

View file

@ -1,9 +1,10 @@
import express from 'express'; import express from 'express';
import { authenticateToken } from '../middlewares/checkAuth';
const ProductrRouter = express.Router(); const productRouter = express.Router();
ProductrRouter.post('/', (req, res) => { productRouter.post('/', authenticateToken, (req, res) => {
res.send('Create product'); res.send('Create product');
}) })
export default ProductrRouter; export default productRouter;

View file

@ -1,9 +1,10 @@
import express from 'express'; import express from 'express';
import { createUser, login } from '../controllers/UserController'; import { createUser, login, logout } from '../controllers/UserController';
const userRouter = express.Router(); const userRouter = express.Router();
userRouter.post('/', createUser); userRouter.post('/', createUser);
userRouter.post('/login', login); userRouter.post('/login', login);
userRouter.post('/logout', logout);
export default userRouter; export default userRouter;