安全与日志

安全与日志

系统安全

Helmet

Helmet 可以通过适当设置 HTTP 标头来帮助保护您的应用程序免受某些知名的网络漏洞的侵害。通常,Helmet 只是 12 个较小的中间件功能的集合,这些功能设置了与安全性相关的 HTTP 响应头。首先,安装所需的软件包:

$ npm i --save helmet

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());

CORS

跨域资源共享(CORS)是一种允许从另一个域请求资源的机制。在底层,Nest 利用了 cors 软件包,该软件包提供了许多选项,您可以根据自己的需求进行自定义。为了启用 CORS,您必须调用 enableCors()方法。

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);

const app = await NestFactory.create(ApplicationModule, { cors: true });
await app.listen(3000);

CSRF

跨站点请求伪造(称为 CSRF 或 XSRF)是一种网站的恶意利用,其中从 Web 应用程序信任的用户发送未经授权的命令。为了减轻这种攻击,您可以使用 csurf 软件包。首先,安装所需的软件包:

$ npm i --save csurf

import * as csurf from 'csurf';
// somewhere in your initialization file
app.use(csurf());

Rate limiting

为了保护您的应用程序免受暴力攻击,您必须实施某种速率限制。幸运的是,NPM 上已经有很多中间件可用。其中之一是 express-rate-limit。

import * as rateLimit from "express-rate-limit";
// somewhere in your initialization file
app.use(
  rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100 // limit each IP to 100 requests per windowMs
  })
);

日志

Nest 随附了一个内置的基于文本的记录器,该记录器可在应用程序引导过程中以及其他几种情况下使用,例如显示捕获的异常(即系统日志记录)。通过 @nestjs/common 包中的 Logger 类提供此功能。您可以完全控制日志记录系统的行为,包括以下任何一项:

  • 完全禁用日志记录
  • 详细说明日志级别(例如,显示错误,警告,调试信息等)
  • 完全覆盖默认记录器
  • 通过扩展默认自定义记录器
  • 利用依赖注入简化应用程序的编写和测试

您还可以使用内置记录器,或创建自己的自定义实现,以记录自己的应用程序级事件和消息。

内置 Logger

要禁用日志记录,请在(可选)作为第二个参数传递给 NestFactory.create()方法的 Nest 应用程序选项对象中将 logger 属性设置为 false,也可以自定义日志级别。

const app = await NestFactory.create(ApplicationModule, {
  logger: false
});

const app = await NestFactory.create(ApplicationModule, {
  logger: ["error", "warn"]
});
await app.listen(3000);

我们也可以自定义日志类:

// 使用 console
const app = await NestFactory.create(ApplicationModule, {
  logger: console
});

// 自定义日志类
import { LoggerService } from "@nestjs/common";

export class MyLogger implements LoggerService {
  log(message: string) {
    /* your implementation */
  }
  error(message: string, trace: string) {
    /* your implementation */
  }
  warn(message: string) {
    /* your implementation */
  }
  debug(message: string) {
    /* your implementation */
  }
  verbose(message: string) {
    /* your implementation */
  }
}

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger()
});

Winston

首先安装依赖:

$ npm install --save nest-winston winston

将 WinstonModule 导入到根 AppModule 中,并使用 forRoot()方法对其进行配置。此方法接受与 winston 包中的 createLogger()函数相同的选项对象:

import { Module } from "@nestjs/common";
import { WinstonModule } from "nest-winston";
import * as winston from "winston";

@Module({
  imports: [
    WinstonModule.forRoot({
      // options
    })
  ]
})
export class AppModule {}

之后,可以使用 winston 注入令牌将 winston 实例注入整个项目:

import { Controller, Inject } from "@nestjs/common";
import { Logger } from "winston";

@Controller("cats")
export class CatsController {
  constructor(@Inject("winston") private readonly logger: Logger) {}
}

请注意,WinstonModule 是全局模块,将在您所有的功能模块中使用。

异步配置

也许您需要异步传递模块选项,例如在需要配置服务时。在这种情况下,请使用 forRootAsync()方法,并从 useFactory 方法返回一个 options 对象:

import { Module } from "@nestjs/common";
import { WinstonModule } from "nest-winston";
import * as winston from "winston";

@Module({
  imports: [
    WinstonModule.forRootAsync({
      useFactory: () => ({
        // options
      }),
      inject: []
    })
  ]
})
export class AppModule {}

工厂可能是异步的,可以使用 inject 选项注入依赖项,并可以使用 imports 选项导入其他模块。另外,您可以使用 useClass 语法:

WinstonModule.forRootAsync({
  useClass: WinstonConfigService
});
下一页