
احرازهویت با اکسپرس ، تایپ اسکریپت و مونگو دیبی
توسعه ی بک اند با اکسپرس ، تایپ اسکریپت و مونگو دیبی
در این مقاله میخوایم با استفاده از فریم ورک اکسپرس با زبان تایپ اسکریپت و دیتابیس مونگو دیبی بک اند سیستم احراز هویت را توسعه داده و دیتای کاربر را در کوکی ها ذخیره و بازیابی کنیم.
۱- ساخت پروژه
در مرحله اول ما ابتدا یک فولدر را برای توسعه بک اند در نظر گرفته و در ترمینال وارد آدرس آن فولدر میشویم و دستورات زیر را در ترمینال اجرا میکنیم :
npm init -y
npm install express
npm install typescript @types/node @types/express ts-node nodemon --save-dev
برای ساخت فایل tsconfig.json کامند زیر را در root پروژه اجرا کنید:
npx tsc --init
و مطمئن شوید که در فایل tsconfig.ts طبق موارد زیر باشد:
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
یک پوشه به اسم src بسازید و در داخل این پوشه یک فایل به اسم index.ts اضافه کرده و کدهای زیر را دا آن وارد کنید:
import express from 'express';
const app = express();
const port = process.env.PORT || 8000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
در فایل package.json بخش scripts اسکریپت های زیر را وارد کنید:
"scripts": {
"start": "node dist/index.js",
"dev": "nodemon src/index.ts",
"build": "tsc"
}
حالا با دستور زیر می توان سروری که ایجاد کرده اید را اجرا کنید و چون از nodemon در اسکریپت dev استفاده کرده ایم با هر تغییری در کد های سرور ریستارت میشود:
npm run dev
و حالا می توانیم توسعه ی بک اند را پیش ببریم و روت های مورد نظر را اضافه کنیم:
۲- توسعه ی کنترلر ها و روت ها:
یک پوشه به اسم controllers در پوشه ی src ایجاد و یک فایل به اسم auth.controller.ts در آن اضافه میکنیم:
import { Request, Response } from "express";
const register = (req: Request, res: Response) => {};
const login = (req: Request, res: Response) => {};
const logout = (req: Request, res: Response) => {};
export { register, login, logout };
و یک پوشه ی دیگه به اسم routes در src ایجاد و در آن یک فایل به اسم auth.router.ts اضافه کرده و کد های زیر را در آن قرار میدهیم :
import express from "express";
import { register, login, logout } from "../controllers/auth.controller";
const router = express.Router();
router.post("/register", register);
router.post("/login", login);
router.post("/logout", logout);
export default router;
تغییرات زیر را جهت افزودن مسیر های احراز هویت به فایل /src/index.ts اضافه میکنیم
import express from "express";
import authRouter from "./routes/auth.router";
const app = express();
app.use("/auth", authRouter);
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
ما برای ادامه ی توسعه نیاز داریم که پکیج های jsonwebtoken و bcryptjs را نصب کنیم :
npm i bcryptjs jsonwebtoken
npm i -D @types/bcryptjs @types/jsonwebtoken
پکیج های jsonwebtoken برای ساخت توکن های jwt جهت احرازهویت استفاده میشود و پکیج bcryptjs برای هش کردن رمز عبور جهت بالا بردن امنیت داده در دیتابیس استفاده میشود.
۳- نصب و راه اندازی دیتابیس در پروژه:
و برای ذخیره ی دیتاها از دیتابیس مونگودیبی استفاده میکنیم برای استفاده از مونگو دیبی باید روی سیستم خود مونگو دیبی رو نصب داشته باشید و یا از یک دیتابیس آنلاین استفاده کنید، جهت ادامه ی کار از ODM مانگوس جهت طراحی و توسعه ی مدل استفاده میکنیم :
npm i mongoose
یک پوشه به اسم models میسازیم و یک فایل به اسم user.model.ts در آن اضافه میکنیم و کد های زیر را در آن وارد میکنیم:
import mongoose, { Document, Schema } from "mongoose";
import bcrypt from "bcryptjs";
export interface IUser extends Document {
name: string;
email: string;
password: string;
comparePassword: (enteredPassword: string) => boolean;
}
const userSchema = new Schema<IUser>({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
// برای هش کردن رمز عبور
userSchema.pre("save", async function (next) {
if (!this.isModified("password")) {
next();
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
});
// برای اعتبار سنجی رمز عبور
userSchema.methods.comparePassword = async function (enteredPassword: string){
return await bcrypt.compare(enteredPassword, this.password);
};
const User = mongoose.model("User", userSchema);
export default User;
در مدل user فیلد های مورد نیاز را به همراه دو متد به اسکیمای user برای هش و اعتبار سنجی پسورد اضافه کردیم که اگر پسورد را در هر جایی از برنامه ویرایش کردیم مقدار آن را هش کند و اگر نیاز به مقایسه و اعتبار سنجی بود بتوان به راحتی انجام داد.
حال برای اتصال به دیتابیس باید یک پوشه به اسم config در src بسازید که شامل یک فایل به نام mongoose.config.ts باشد و کد های زیر را در آن وارد کنید:
import {default: mongoose} from "mongoose";
const mongoosConnection = async () => {
try {
const mongo_url = "mongodb://localhost:27017/codenight";
await mongoose.connect(mongo_url).then(() => {
console.log("MongoDB Connected");
})
} catch (error: any) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
};
export default mongoosConnection;
۴- کار با کوکی ها جهت ذخیره سازی توکن:
در پوشه ی src یک پوشه به اسم utils ایجاد و فایل auth.ts را در آن بسازید و کد های زیر را در آن قرار دهید:
import jwt from "jsonwebtoken";
import { Response } from "express";
const generateToken = (res: Response, userId: string) => {
const jwtSecret = process.env.JWT_SECRET || "";
const token = jwt.sign({ userId }, jwtSecret, {
expiresIn: "1h",
});
res.cookie("jwt", token, {
httpOnly: true,
secure: process.env.NODE_ENV !== "development",
sameSite: "strict",
maxAge: 60 60 1000,
});
};
const clearToken = (res: Response) => {
res.cookie("jwt", "", {
httpOnly: true,
expires: new Date(0),
});
};
export { generateToken, clearToken };
در کد های فوق ما ۲ تابع را توسعه دادیم تابع generateToken برای ساخت jwt توکن و ذخیره کردن توکن در کوکی و همچنین تابع clearToken برای پاک کردن توکن در کوکی ها استفاده می شود که در بخش احراز هویت جهت وارد شدن و خارج شدن از حساب کاربری استفاده میشوند.
۵- قرار دادن لاجیک مربوط به کنترلر auth:
سپس وارد فایل auth.controller.ts شوید و کد های زیر را جایگزین کنید:
import { Request, Response } from "express";
import User from "../models/User";
import { generateToken, clearToken } from "../utils/auth";
const register = async (req: Request, res: Response) => {
const { name, email, password } = req.body;
const userExists = await User.findOne({ email });
if (userExists) {
res.status(409).json({ message: "The user already exists" });
}
const user = await User.create({
name,
email,
password,
});
if (user) {
generateToken(res, user._id);
res.status(201).json({
id: user._id,
name: user.name,
email: user.email,
});
} else {
res.status(400).json({
message: "An error occurred in creating the user"
});
}
};
const login = async (req: Request, res: Response) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user && (await user.comparePassword(password))) {
generateToken(res, user._id);
res.status(201).json({
id: user._id,
name: user.name,
email: user.email,
});
} else {
res.status(401).json({ message: "User not found / password incorrect" });
}
};
const logout = (req: Request, res: Response) => {
clearToken(res);
res.status(200).json({ message: "User logged out" });
};
export { register, login, logout };
در کد های فوق کنترلر مربوط به احراز هویت را توسعه دادیم که متد register برای ثبت نام کاربر و متد login برای ورود کاربر به حساب کاربری و همچنین متد logout برای خارج شدن از حساب کاربری استفاده می شوند
حال فایل index.ts را در فولدر src را بازکنید و کد های زیر را جایگزین کنید:
import express = from "express";
import mongooseConnection from "./config/mongoose.config";
import authRoute from "./routes/auth.router";
const app = express();
const PORT = 8000;
//اتصال به دیتابیس
mongooseConnection();
// میدلویر های مربوط به دریافت دیتا از طریق body
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
//میدلویر راه اندازی کوکی
app.use(cookieParser());
// Set CORS headers
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", process.env.FRONTEND_URL); // Replace with your frontend domain
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.header("Access-Control-Allow-Credentials", "true"); // Allow credentials (cookies, etc.)
next();
});
app.use("/auth", authRoute);
app.listen(PORT, () => {
console.log(`Server is running on PORT ${PORT}`);
});
CORS یک قابلیت توی مرورگرها هست که به سرورها این امکان رو میده تا تعیین کنن که منابع سرور (عکس، متن و ...) برای کدوم دامنهها قابل دسترس باشد.
که با اجرا کردن دستور
npm run dev
برنامه ی ما اجرا میشود.
امیدوارم از این مقاله خوشتون اومده باشه با نظرات و لایک هاتون حمایت کنید ❤️🙏🏻
سلام دوستان من عرفانم و از سال۹۰ وارد حوزه ی برنامه نویسی شدم و توی حوزه های مختلفی فعالیت داشتم و در سال ۹۴ وارد حوزه ی برنامه نویسی وب شدم و به صورت تخصصی حوزه ی بک اند رو پیش بردم و همچنین از سال ۹۹ تدریس رو شروع کردم و روز به روز تجربه ام توی تدریس داره بیشتر میشه ، تجربیات خیلی زیادی رو توی مسیر برنامه نویسی کسب کردم. شکست ها و موفقیت هایی رو هم داشتم که همه ی این تجربیات رو سعی کردم توی دوره ها در اختیارتون بذارم.