متن خبر

نحوه افزودن احراز هویت مبتنی بر JWT در NestJS

نحوه افزودن احراز هویت مبتنی بر JWT در NestJS

شناسهٔ خبر: 665401 -




احراز هویت یک جنبه بسیار مهم در توسعه نرم افزار است. این فرآیند تأیید هویت کاربر است.

احراز هویت تضمین می کند که فقط افراد مجاز به منابع خاصی دسترسی دارند یا اقدامات خاصی را در یک سیستم انجام می دهند. با فعال کردن ردیابی اقدامات کاربر و مسئول نگه داشتن افراد در قبال فعالیت هایشان، مسئولیت پذیری را فراهم می کند.

همچنین داده هایی را در مورد تعداد افرادی که از محصولات آنها استفاده می کنند به شرکت ها می دهد. بدون احراز هویت مناسب نرم افزار خود، ممکن است با خطرات امنیتی روبرو شوید. اجرای صحیح از دسترسی غیرمجاز جلوگیری می کند و از داده های حساس محافظت می کند.

این آموزش شما را در ساخت یک احراز هویت کاربر مبتنی بر JWT در NestJS و MongoDb راهنمایی می کند.

NestJS یک چارچوب قدرتمند Node.js برای ساخت سمت سرور است
برنامه های کاربردی. MongoDB پایگاه داده محبوب NoSQL است و ما از آن برای ساختن نقاط پایانی احراز هویت اولیه استفاده خواهیم کرد.

در این آموزش به موضوعات زیر می پردازیم:

نحوه ایجاد یک پروژه جدید NestJS و نصب وابستگی های لازم.

نحوه ایجاد مدل ها و طرحواره های کاربری

نحوه پیاده سازی ورود و ثبت نام با توکن JWT.

نحوه تست نقاط پایانی با پستچی

پیش نیازها

این آموزش یک دمو عملی است. برای دنبال کردن، باید آن را داشته باشید
ذیل:

Node.js نسخه 14
و بالاتر

مدیر بسته گره

MongoDB
قطب نما

درک اولیه Node.js و ترجیحا ExpressJs

یک ویرایشگر کد (به عنوان مثال: VS Code)

نحوه راه اندازی پروژه

در این بخش، پروژه ای را برای ساخت REST API خود راه اندازی می کنیم
NestJS و MongoDB. ما با نصب NestJS CLI و استفاده از آن برای تولید پروژه های جدید شروع می کنیم.

Nest CLI را نصب کنید:

$ npm i -g @nestjs/cli

سپس با این دستور یک پروژه جدید NestJS ایجاد کنید:

$ nest new project-name

بیایید احراز هویت پروژه را صدا کنیم:

$ nest new authentication

گزینه هایی در مورد اینکه کدام مدیر بسته را ترجیح می دهید نصب کنید را مشاهده خواهید کرد. من
npm استفاده شده است.

پس از نصب موفقیت آمیز، به پوشه ایجاد شده بروید و باز کنید
پروژه با ویرایشگر کد دلخواه شما.

قبل از اینکه به ایجاد منابع و پیکربندی پروژه بپردازیم، اجازه دهید
نگاهی گذرا به دایرکتوری src و فایل های آن بیندازید:

src : دایرکتوری ریشه برای کد منبع.

src/app.module.ts : ماژول اصلی برنامه برای پیکربندی و
ادغام ماژول های دیگر

src/app.controller.ts : شامل یک کنترلر پیش فرض با یک واحد است
مسیر

src/app.service.ts : این شامل یک سرویس پایه با استفاده از یک واحد است
روش.

src/main.ts : نقطه ورود برنامه.

در مرحله بعد، وابستگی ها را برای راه اندازی و اتصال پایگاه داده نصب کنید. شما باید بسته mongoose ، bcrypt را نصب کنید:

$ npm i -save @nestjs/mongoose @types/bcrypt mongoose bcrypt

وابستگی ها با موفقیت نصب شدند

بعد، پایگاه داده خود را تنظیم کنید. MongooseModule از وابستگی @nestjs/mongoose برای راه اندازی پایگاه داده استفاده خواهد شد.

به فایل src/app.module.ts بروید:

 import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MongooseModule } from '@nestjs/mongoose'; import { UsersModule } from './users/users.module'; import { AuthModule } from './auth/auth.module'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ MongooseModule.forRoot('mongodb://localhost:27017/auth-workshop'), UsersModule, AuthModule, ConfigModule.forRoot({ envFilePath: '.env', isGlobal: true, }), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}

بیایید کد بالا را تجزیه کنیم.
app.module.ts ماژول اصلی برنامه nestjs است و وظیفه وارد کردن وابستگی ها و سایر ماژول های مورد نیاز برنامه، پیکربندی برنامه مانند اتصالات پایگاه داده و متغیرهای محیطی را بر عهده دارد.

ما ابتدا فایل app.module.ts را به عنوان یک ماژول با استفاده از دکوراتور @Module({}) مشخص کردیم:

 @Module({})

آرایه imports ماژولی را مشخص می کند که این ماژول به آن وابسته است. ما MongooseModule.forRoot('') برای اتصال به پایگاه داده با استفاده از mongoose داریم، ConfigModule.forRoot import ماژول پیکربندی را برای خواندن از یک فایل .env تنظیم می کند:

 import { MongooseModule } from '@nestjs/mongoose'; import { UsersModule } from './users/users.module'; import { AuthModule } from './auth/auth.module'; import { ConfigModule } from '@nestjs/config'; imports: [ MongooseModule.forRoot('mongodb://localhost:27017/auth-workshop'), UsersModule, AuthModule, ConfigModule.forRoot({ envFilePath: '.env', isGlobal: true, }), ]

شما می توانید رشته URI MongooseModule.forRoot() را با پایگاه داده خود جایگزین کنید
رشته

آرایه controllers کنترل کننده ای را که به این ماژول تعلق دارد را مشخص می کند:

 controllers: [AppController]

آرایه providers خدمات متعلق به این ماژول را مشخص می کند:

 providers: [AppService]

با این تنظیمات می توانید برنامه خود را با استفاده از
npm run start:dev .

مدل ها و طرحواره های کاربر

در این بخش، مدل User و طرحواره را با استفاده از آن تعریف می کنیم
mongoose . مدل User نشان دهنده کاربران برنامه خواهد بود،
و این طرح ساختار داده های ذخیره شده در MongoDB را تعریف می کند.
بیایید با ایجاد یک ماژول منبع برای API کاربران شروع کنیم:

ابتدا یک منبع users با CLI تودرتو ایجاد کنید:

$ nest generate res users

این دستور یک منبع users جدید در src/users ایجاد می کند
دایرکتوری با ساختار پایه ای از کنترلرها و خدمات.

سپس طرحی را برای Users در src/users/entities/users.entity.ts تعریف کنید:

 import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; @Schema() export class User { @Prop() name: string; @Prop({ unique: true }) email: string; @Prop() password: string; } export const UserSchema = SchemaFactory.createForClass(User);

دکوراتور @Schema چیزی است که کلاس را به یک طرحواره تبدیل می کند. این طرح سه فیلد را برای کاربران تعریف می کند: name ، email و password . همه آنها رشته ای تایپ شده اند.

سپس، طرح را در فایل users.module.ts واقع در src/users/users.module.ts ثبت کنید:

 import { Module } from '@nestjs/common'; import { UsersService } from './users.service'; import { UsersController } from './users.controller'; import { MongooseModule } from '@nestjs/mongoose'; import { UserSchema, User } from './entities/user.entity'; @Module({ imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])], controllers: [UsersController], providers: [UsersService], }) export class UsersModule {}

با وارد کردن MongooseModule.forFeature([{}]) ، mongoose را برای استفاده از UserSchema برای مدل User پیکربندی می‌کند.

با ثبت طرح با Mongoose، مدلی ایجاد کردیم که آماده استفاده در برنامه ما است. این زمینه را برای ساختن خدمات و کنترل‌کننده‌هایی فراهم می‌کند که می‌توانند با داده‌های ما تعامل داشته باشند و درخواست‌های دریافتی را مدیریت کنند.

در نهایت، DTO (شیء انتقال داده) را تعریف کنید. این شی داده ها را بین سیستم ها منتقل می کند. این یک شی ساده است که فقط حاوی داده است و هیچ رفتاری ندارد.

CreateUserDto خود را در دایرکتوری src/users/dto/create-user.dto.ts ایجاد کنید:

 export class CreateUserDto { username: string; email: string; password: string; }

خدمات کاربر و کنترلرها

ما به پایگاه داده متصل شده ایم و طرح و مدل Users را ایجاد کرده ایم. بیایید روش های اولیه CRUD را برای کاربران بنویسیم.

users.service.ts خود را که در src/users/users.service.ts قرار دارد به روز کنید:

 import { Injectable, NotFoundException } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; import { InjectModel } from '@nestjs/mongoose'; import { User } from './entities/user.entity'; import { Model } from 'mongoose'; @Injectable() export class UsersService { constructor(@InjectModel(User.name) private userModel: Model<User>) {} async createUsers(createUserDto: CreateUserDto) { const user = await this.userModel.create(createUserDto); return user.save(); } async findAllUsers() { const users = this.userModel.find(); return users; } async findUser(id: number) { const user = await this.userModel.findById(id); if (!user) throw new NotFoundException('could not find the user'); return user; } updateUser(id: number, updateUserDto: UpdateUserDto) { return this.userModel.findByIdAndUpdate(id, updateUserDto, { new: true }); } removeUser(id: number) { return this.userModel.findByIdAndDelete(id); }; }

users.controller.ts خود را که در src/users/users.controller.ts قرار دارد به روز کنید:

 import { Controller, Get, Post, Body, Patch, Param, Delete, } from '@nestjs/common'; import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Post() async create(@Body() createUserDto: CreateUserDto) { return await this.usersService.createUsers(createUserDto); } @Get() async findAll() { return await this.usersService.findAllUsers(); } @Get(':id') async findOne(@Param('id') id: string) { return await this.usersService.findOneUser(+id); } @Patch(':id') async update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) { return await this.usersService.updateUser(+id, updateUserDto); } @Delete(':id') async remove(@Param('id') id: string) { return await this.usersService.removeUser(+id); } }

ما API های RESTful را با استفاده از mongoose ایجاد کردیم. روش ها عبارتند از:

findAllUsers : تمام اسناد کاربر را از مجموعه بازیابی می کند.

getUserById : یک سند کاربر را بر اساس شناسه پیدا می کند.

createUsers : یک سند کاربر جدید را به مجموعه اضافه می کند.

updateUser : جزئیات کاربر موجود در مجموعه را به روز می کند.

removeUser : سند کاربر را با شناسه حذف می کند.

نحوه پیاده سازی ثبت نام و ورود به سیستم

در این بخش، یک سرویس احراز هویت ایجاد می کنیم که توکن های وب JSON (JWT) را تولید می کند.

این سرویس دو روش دارد: signup و login . signup
متد یک شی درخواست ثبت نام شامل name ، email و
password ) و روش login یک شی درخواست ورود به سیستم را می گیرد
حاوی email و password هر دو روش یک JWT برمی گرداند.

بیایید با ایجاد یک ماژول منبع برای APIهای احراز هویت شروع کنیم.

ایجاد منبع auth با Nest CLI:

$ nest generate res auth

سپس DTO را هم برای ثبت نام و هم برای ورود تعریف کنید. به پوشه dto در پوشه src/auth/dto بروید:

signup.dto.ts :

 export class SignUpDto { name: string; email: string; password: string; }

login.dto.ts :

 export class Login { email: string; password: string; }

سپس یک فایل .env در دایرکتوری ریشه ایجاد کنید:

 JWT_SECRET=secret JWT_EXPIRES=3d

سپس PassportModule ، JwtModule و JwtStrategy را به AuthModule اضافه کنید. ما با نصب این بسته ها شروع می کنیم:

$ npm i @nestjs/passport @nestjs/jwt passport passport-jwt bcryptjs

به src/auth/auth.module.ts بروید و این بسته ها را وارد کنید:

 import { Module } from '@nestjs/common'; import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; import { PassportModule } from '@nestjs/passport'; import { JwtModule } from '@nestjs/jwt'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { MongooseModule } from '@nestjs/mongoose'; import { UserSchema } from 'src/users/entities/user.entity'; @Module({ imports: [ PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => { return { secret: config.get<string>('JWT_SECRET'), signOptions: { expiresIn: config.get<string | number>('JWT_EXPIRES'), }, }; }, }), MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]), ], controllers: [AuthController], providers: [AuthService], }) export class AuthModule {}

PassportModule.register ماژول Passport را برای استفاده از استراتژی JWT به عنوان مکانیزم احراز هویت پیکربندی می کند.

JwtModule.registerAsync ماژول JWT را با استفاده از فرآیند ثبت نام ناهمزمان، مانند زمان انقضای رمز، پیکربندی می کند.

MongooseModule.forFeature() mongoose را برای ما UserSchema برای مدل User پیکربندی می کند.

این واردات، ماژول احراز هویت را قادر می سازد تا احراز هویت کاربر، تولید JWT و تعامل پایگاه داده را مدیریت کند.

سپس، AuthServices برای ثبت نام ایجاد کنید و در دایرکتوری src/auth/auth.service.ts وارد شوید:

 import { Injectable, UnauthorizedException} from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { User } from 'src/users/entities/user.entity'; import { SignUpDto } from './dto/signup.dto'; import * as bcrypt from 'bcryptjs'; import { LoginDto } from './dto/login.dto'; import { ConfigService } from '@nestjs/config'; @Injectable() export class AuthService { constructor( @InjectModel(User.name) private userModel: Model<User>, private jwtService: JwtService, private configService: ConfigService, ) {} async signUp(signupDto: SignUpDto) { const { name, email, password } = signupDto; const hashedPassword = await bcrypt.hash(password, 10); const user = await this.userModel.create({ name, email, password: hashedPassword, }); await user.save(); const token = await this.jwtService.sign( { id: user.id }, { secret: this.configService.get('JWT_SECRET'), expiresIn: this.configService.get('JWT_EXPIRES'), }, ); return { token }; } async login(loginDto: LoginDto) { const { email, password } = loginDto; const user = await this.userModel.findOne({ email, }); if (!user) throw new UnauthorizedException('invalid email or password'); const passwordMatch = await bcrypt.compare(password, user.password); if (!passwordMatch) throw new UnauthorizedException('invalid email or password'); const token = await this.jwtService.sign( { id: user.id }, { secret: this.configService.get('JWT_SECRET'), }, ); return { token }; } }

در AuthService ، روش signUp ثبت نام کاربر را توسط:

تخریب شی SignupDto برای استخراج اعتبار کاربر.

هش کردن رمز عبور با استفاده از bcrypt برای ذخیره سازی ایمن.

ایجاد یک سند کاربر جدید در پایگاه داده از طریق userModel .

ذخیره سند کاربر در پایگاه داده

تولید یک توکن JWT با استفاده از jwtService پس از ثبت نام موفقیت آمیز.

بازگرداندن توکن JWT به مشتری.

روش login احراز هویت کاربران را توسط:

تخریب شی LoginDto برای تأیید اعتبار کاربر.

مقایسه رمز عبور ورودی با هش ذخیره شده برای اطمینان از مطابقت.

پرتاب خطای UnauthorizedException در صورت عدم تطابق رمزهای عبور.

استفاده از jwtService برای امضای کاربر و تولید توکن JWT پس از احراز هویت موفق.

بازگرداندن توکن JWT به مشتری.

AuthController برای ثبت نام و ورود به دایرکتوری src/auth/auth.controller.ts به روز کنید:

 import { Controller, Post, Body } from '@nestjs/common'; import { AuthService } from './auth.service'; import { SignUpDto } from './dto/signup.dto'; import { LoginDto } from './dto/login.dto'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Post('signup') signUp(@Body() signupDto: SignUpDto) { return this.authService.signUp(signupDto); } @Post('login') signin(@Body() loginDto: LoginDto) { return this.authService.login(loginDto); } }

با این مراحل، یک ورود و ثبت نام اولیه کاربر را در برنامه خود پیاده سازی کرده اید. در بخش های بعدی، مسیرهای login و signup را آزمایش خواهیم کرد.

تست در پستچی

اکنون که نقاط پایانی خود را تنظیم کرده‌ایم، وقت آن است که آنها را آزمایش کنیم.
برای این مثال، من از Postman به عنوان مشتری API خود استفاده خواهم کرد، اما خیالتان راحت باشد
برای استفاده از هر ابزار یا مشتری متناسب با نیاز شما. بیایید API خود را در آن ببینیم
عمل!

نحوه ایجاد کاربر با /signup Endpoint:

تست ثبت نام پستچی

پس از ارسال درخواست POST به نقطه پایانی /signup با استفاده از Postman، ما
پاسخی حاوی AccessToken دریافت کرد. شما می توانید تأیید کنید که جدید است
کاربر با تحلیل پایگاه داده با موفقیت ایجاد شد.

تایید ثبت نام قطب نما mongodb

به عنوان یک کاربر موجود با /login endpoint وارد شوید:

تست ورود پستچی

نتیجه

تبریک می گویم، شما با موفقیت جامع را اجرا کردید
احراز هویت با استفاده از NestJS، Mongoose و Passport. ما یک امن طراحی کردیم
فرآیند ثبت نام و ورود به سیستم و ایجاد توکن های وب JSON (JWT).

برای بهبود بیشتر و گسترش دانش خود در مورد احراز هویت، نگاه کنید
به مجوز، محافظت از مسیرها با میان افزار احراز هویت،
و اجرای تایید ایمیل و قابلیت بازنشانی رمز عبور.

این پایه یک نقطه شروع محکم برای ساختن یک ساختمان قوی فراهم می کند
و سیستم احراز هویت مقیاس پذیر. این پروژه برای کار لذت بخش بود
در، و من امیدوارم که شما آن را به همان اندازه لذت بخش بود.

برای راحتی شما، مخزن پروژه در Github در دسترس است .

لطفاً در ارتباط با من در توییتر در Adedot1Abimbola@ تردید نکنید.
من دوست دارم از شما بشنوم

خبرکاو

ارسال نظر

دیدگاه‌ها بسته شده‌اند.


تبليغات ايهنا تبليغات ايهنا

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