احرازهویت با اکسپرس ، تایپ اسکریپت و مونگو دیبی
زمان مطالعه: 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

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

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

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

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

سلام دوستان من عرفانم و از سال۹۰ وارد حوزه ی برنامه نویسی شدم و توی حوزه های مختلفی فعالیت داشتم و در سال ۹۴ وارد حوزه ی برنامه نویسی وب شدم و به صورت تخصصی حوزه ی بک اند رو پیش بردم و همچنین از سال ۹۹ تدریس رو شروع کردم و روز به روز تجربه ام توی تدریس داره بیشتر میشه ، تجربیات خیلی زیادی رو توی مسیر برنامه نویسی کسب کردم. شکست ها و موفقیت هایی رو هم داشتم که همه ی این تجربیات رو سعی کردم توی دوره ها در اختیارتون بذارم.

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