EN

Search
Close this search box.

موستانگ، وحشیِ دوست داشتنی

پاسخ داده شد
0
0

چطور از سرویس های back-end مان محافظت کنیم؟ چه GET باشد چه POST ، UPDATE ، PATCH و DELETE

  • شما باید برای ارسال دیدگاه شوید
پاسخ عالی
0
0

فرض کنید سرویس های مختلفی (GET,POST,DELETE,PATCH,UPDATE) برای back-end نوشتیم، اگر آدرس و پورت back دست هر شخصی بیفتد ، می تواند سرویس های شما را فراخوانی کند (مثلاً پستی یا همه پست ها را حذف کند، آپدیت کند و …)

برای جلوگیری از دسترسی افراد احراز هویت نشده باید چکار کنیم؟

برای این کار باید برای هر سرویس Guard تعریف کنیم. با گذاشتن decorator ای بنام UseGuards@ بالای هر تایع controller می توانیم کاری کنیم که آن تابع تنها پس از احراز هویت اجرا شود. برای احراز هویت هم الگوریتم های مختلفی وجود دارد که ما از یکی از ممعروفترین آن ها یعنی JWT استفاده می کنیم. نام الگوریتمی که استفاده می کنیم باید کنار decorator نوشته شود. یعنی تابع deleteای که داخل controller نوشتیم ، به این صورت در می آید:

@UseGuards(JwtAuthGuard)
@Delete(":_id")
  async deletePage(
    @Param("_id") _id: string) {
    return await this.pagesService.deletePage(_id);
  }

JWT چطور احراز هویت می کند؟

jwt مخفف json web token است و بدین صورت عمل می کند که وقتی کاربر احراز هویت شد و لاگین کرد، یک توکن با محتوایی که می خواهیم (مثلا شامل id و role کاربر، یا هر داده ای که می خواهیم) می سازیم ، رمزنگاری می کنیم و به front-end می فرستیم. قسمت front-end ، این توکن رمزنگاری شده را در local storage  ذخیره می کند و هر زمان خواست http request ای به back-end بفرستد، این توکن را داخل header قرار می دهد و می فرستد. back-end هم این توکن را می گیرد، باز می کند و اگر درست بود، درخواست احراز هویت می شود و تابع مذکور اجرا می شود. در اینصورت تنها کسانی می توانند تابع ما را اجرا کنند که توکن داشته باشند.

*دقت کنید که می توانیم برای توکن تاریخ انقضا تعریف کنیم. (مثلاً اگر کاربر داخل کافی نت لاگین کرده و توکن آنجا ذخیره شده باشد، ممکن است شخص دیگه ای به توکن دسترسی پیدا کن)

برای استفاده از jwt ، لازم است تا کتابخانه های زیر را نصب کنید:

npm install @nestjs/jwt
npm install passport-jwt
npm install jsonwebtoken

 

چطور بعد از لاگین کاربر، توکن بسازیم و ارسال کنیم؟

در تابعی که برای لاگین کاربر نوشته اید، jsonwebtoken را ایمپورت کنید:

import * as jwt from 'jsonwebtoken';

و به صورت زیر یک توکن بسازید و امضایش کنید:

async tokenGenerator(payload:AuthPayload)
      {
        return jwt.sign(payload,process.env.ACCESS_JWT_SECRET);
      }

*AuthPayload مدلی است که برای توکن تعریف کرده ایم. شما هر داده ای از کاربر را می توانید به عنوان توکن تعریف کنید. مثلا ما AuthPayload را در فولدری بنام auth و بدین صورت تعریف کرده ایم:

export class AuthPayload
{
    user_id:string;
    role:string;
    
}

*payload به معنای توکنی است که رمزش باز شده.

*اکیدا توصیه می شود که کلیدی که توکن به وسیله آن رمزنگاری شده و باز می شود را در فایل env. و به عنوان environment variable ذخیره کنید.

*وقتی کاربر با موفقیت لاگین شد، باید این توکن را به فرانت ارسال کنیم و فرانت هم باید آن ها در local storage ذخیره کند.

 

چطور JwtAuthGuard را بسازیم؟

فولدری بنام auth بسازیم و داخل آن باید دو فایل اصلی برای guard و strategy داشته باشید.

فایل jwt-auth-guard.ts را بدین صورت تعریف کنید:

import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt')
{

}

فایل jwt-strategy.ts را بدین صورت تعریف کنید:

import {PassportStrategy} from "@nestjs/passport";
import {ExtractJwt, Strategy} from "passport-jwt";
import { Injectable} from "@nestjs/common";


@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor() {

        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: process.env.ACCESS_JWT_SECRET,
        })
    }

    async validate(payload: any) {
        
        return {user_id: payload.user_id, role: payload.role}
    }

 
}

حالا کافی است تا در فایل کنترلری که می خواهیم از guard استفاده کنیم، JwtAuthGuard را ایمپورت کنیم:

import { JwtAuthGuard } from "src/auth/jwt-auth-guard";

و بالای تابع موردنظرمان، از decorator زیر استفاده کنیم:

 @UseGuards(JwtAuthGuard)

 

*بهتر است auth را بصورت ماژول در آورید (حتی می توانید تابع تولید کننده توکن tokenGenerator ، را داخل AuthService قرار دهید):

import { Module } from "@nestjs/common"
import { PassportModule } from "@nestjs/passport"
import { UsersModule } from "src/users/users.module"
import { AuthService } from "./auth.service"


@Module({
  imports: [PassportModule.register({ session: true })],
  providers: [AuthService],
})
export class AuthModule {}

*دقت کنید که باید داخل فایل app.module هم jwt را ایمپورت کرده و به عنوان ماژل اضافه کنید:

import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './auth/strategy/jwt-strategy';




@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({secret: process.env.ACCESS_JWT_SECRET}), 
    AuthModule],

  controllers: [AppController],
  providers: [AppService,JwtStrategy],
})

export class AppModule {}

چطور در فرانت ، توکن را داخل http request قرار دهیم و ارسال کنیم؟

به صورت زیر می توانید header درخواستتان را بسازید (توکن را از local storage بگیرید و داخل آن قرار دهید):

const token = JSON.parse(localStorage.getItem('Token'));
const config = {  headers: {"Content-Type": "application/json",Authorization: `Bearer ${token}`} }

حالا header را داخل درخواست axios قرار دهید:

axios.patch("BACK_END_ADRESS", data, config);
  • شما باید برای ارسال دیدگاه شوید
نمایش 1 نتیجه
پاسخ شما
اگر قبلاً حساب کاربری دارید با پر کردن فیلد های زیر یا به عنوان مهمان ارسال کنید.
نام*
ایمیل*
وب سایت