安全与日志
安全与日志
系统安全
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
});