一 :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,},],
})