一 :nest/cli? 常見命令
1 生成中間件。 nest g middle name (生成中間件)
2 生成攔截器。? nest g interceptor name xxx
3?生成守衛。? nest g gu name xxx
二: 如何在項目中如何應用多個中間件?
import { Injectable, NestMiddleware } from '@nestjs/common';@Injectable()
export class Mid1Middleware implements NestMiddleware {use(req: any, res: any, next: () => void) {console.log("middle1-----")next();}
}----------------------------------------
import { Injectable, NestMiddleware } from '@nestjs/common';@Injectable()
export class Mid2Middleware implements NestMiddleware {use(req: any, res: any, next: () => void) {console.log("middle2-----")next();}
}
step2:改寫app.module.ts
export class AppModule implements NestModule{configure(consumer: MiddlewareConsumer) {consumer.apply(Mid1Middleware,Mid2Middleware).forRoutes("*")// consumer.apply(Mid2Middleware).forRoutes("*")}}
apply方法中傳入多個中間件函數名稱即可
三:如何實現http的攔截器?
step1 :?nest g interceptor interceptor/reqest? ? |? ? nest g interceptor interceptor/response
該命令將生成目錄interceptor,且包含reqest和response兩個函數
setp2 :?
request
-----------------------------------import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';@Injectable()
export class ReqestInterceptor implements NestInterceptor {intercept(context: ExecutionContext, next: CallHandler): Observable<any> {console.log("before request-----")return next.handle();}
}response
-----------------------------------
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, map } from 'rxjs';@Injectable()
export class ResponseInterceptor implements NestInterceptor {intercept(context: ExecutionContext, next: CallHandler): Observable<any> {console.log("response request----")return next.handle().pipe(map(data=>({data,status:200,message:'ok'})))}
}//在返回值中我們定義了攔截以后的數據格式
step3 :應用攔截器
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import {ResponseInterceptor} from "./interceptor/response/response.interceptor"
@Controller()
export class AppController {constructor(private readonly appService: AppService) {}@Get()getHello(): string {return this.appService.getHello();}@Get('list')@UseInterceptors(ResponseInterceptor) //這里是關鍵,UseInterceptors裝飾器可以對制定的路由進行攔截getList(){let arr=[{id:1,name:"aaaa"},{id:2,name:"bbbbb"},{id:3,name:"ccccc"},{id:4,name:"dddddd"},]return arr //我們只需要正常返回數據即可,攔截器會自動把最后的數據格式進行轉換}
}
提示:這里我們是針對某些具體的請求做了攔截處理,包括返回值格式化,如果要對全局所有接口都作統一的處理,這時候我們需要做如下更改
app.module.ts中
import { APP_INTERCEPTOR } from '@nestjs/core';
import { ResponseInterceptor } from './interceptor/response/response.interceptor';
import { ReqestInterceptor } from './interceptor/reqest/reqest.interceptor';
@Module({imports: [],controllers: [AppController],providers: [AppService,{provide:APP_INTERCEPTOR,useClass:ReqestInterceptor},{provide:APP_INTERCEPTOR,useClass:ResponseInterceptor}],
})
export class AppModule implements NestModule{configure(consumer: MiddlewareConsumer) {consumer.apply(Mid1Middleware,Mid2Middleware).forRoutes("*")// consumer.apply(Mid2Middleware).forRoutes("*")}}
providers選項中我們引入了APP_INTERCEPTOR選項。同時應用RequestInterceptor和ResponseInterceptor,這樣就能實現全局的路由攔截
四:nest如何守衛?(以判斷請求中是否有token為例)
step1: nest g gu AuthGurd
step2:?
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';@Injectable()
export class AuthgurdGuard implements CanActivate {canActivate(context: ExecutionContext,): boolean | Promise<boolean> | Observable<boolean> {const request =context.switchToHttp().getRequest()const token=request.headers['authorization']if(token && token ==='abc123'){return true}return false;}
}
step3:在controller中對請求作守衛
import { Controller, Get, UseGuards, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import {ResponseInterceptor} from "./interceptor/response/response.interceptor"
import { AuthgurdGuard } from './authgurd/authgurd.guard';
@Controller()export class AppController {constructor(private readonly appService: AppService) {}@Get()getHello(): string {return this.appService.getHello();}@Get('list')@UseGuards(AuthgurdGuard)// @UseInterceptors(ResponseInterceptor)getList(){let arr=[{id:1,name:"aaaa"},{id:2,name:"bbbbb"},{id:3,name:"ccccc"},{id:4,name:"dddddd"},]return arr}
}
以上我們以list接口為例,請求http://localhost:3000/list如果header中沒有token則會報錯,而其他接口則不受影響。
同樣,如果想讓AuthGuard全局生效。則可以在app.module.ts中采用如下方式:
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { AuthgurdGuard } from './authgurd/authgurd.guard';@Module({imports: [],controllers: [AppController],providers: [AppService,{provide:APP_GUARD, //這里是核心useClass: AuthGuard,},],
})