احرازهویت با اکسپرس ، تایپ اسکریپت و مونگو دیبی
زمان مطالعه: 10 دقیقه
۱۴۰۲/۱۲/۱۱

احرازهویت با اکسپرس ، تایپ اسکریپت و مونگو دیبی

توسعه ی بک اند با اکسپرس ، تایپ اسکریپت و مونگو دیبی

در این مقاله میخوایم با استفاده از فریم ورک اکسپرس با زبان تایپ اسکریپت و دیتابیس مونگو دیبی بک اند سیستم احراز هویت را توسعه داده و دیتای کاربر را در کوکی ها ذخیره و بازیابی کنیم.

۱- ساخت پروژه

در مرحله اول ما ابتدا یک فولدر را برای توسعه بک اند در نظر گرفته و در ترمینال وارد آدرس آن فولدر میشویم و دستورات زیر را در ترمینال اجرا میکنیم :


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

برنامه ی ما اجرا میشود.

امیدوارم از این مقاله خوشتون اومده باشه با نظرات و لایک هاتون حمایت کنید ❤️🙏🏻

پروفایل عرفان یوسفی

نویسنده مقاله

از سال ۸۹ - ۹۰ وارد حوزه ی برنامه نویسی شدم و انواع زمینه ها و شاخه های مختلف رو کار کردم تا اینکه سال ۹۵ توی حوزه ی بک اند (نود جی اس) ماندگار شدم، تجربیات خیلی زیادی رو توی این مسیر کسب کردم. شکست ها و موفقیت هایی رو هم داشتم که همه ی این موارد رو در قالب مقاله، دوره و پادکست در اختیارتون خواهم گذاشت خلاصه که وبسایت کدنایت رو سال ۱۴۰۲ توسعه دادیم که یک پلتفرم آموزشی با گروهی از اساتید خفن هستش که قراره کلی محتوا در اختیارتون بذاریم.

دیدگاه ها و پرسش ها