【NestJS应用从0到1】2.认证及日志

199 阅读2分钟

简介:用户认证JWTTypeORM-mysql,日志-winston,环境变量

常见应用都有部分功能或页面需要用户登录进行访问,所以我们肯定会引入用户体系以及用户登录认证等。 NestJS的官方文档其实已经足够详细了,推荐使用对着官方文档查看即可。

认证

直接读官方文档/安全-认证才是最快的。

数据库-使用TypeORM 持久化

这里也只做传送门,读官方文档-中文/数据库

让配置更优雅

app.module.ts中引入winston配置时,可以将配置文件单独出来,这样代码看起来会更整洁


import { mysqlConfig, entities } from './configs/mysql.config';
...
@Module({
 imports: [
    TypeOrmModule.forFeature(entities),
    // 数据库持久化 ORM
    TypeOrmModule.forRootAsync(mysqlConfig),
    ]
})

在配置文件中,将DB的配置放在.env环境变量中,使用configService来读取


import { TypeOrmModuleAsyncOptions } from '@nestjs/typeorm';
import { EntityClassOrSchema } from '@nestjs/typeorm/dist/interfaces/entity-class-or-schema.type';
import { User } from '../users/user.entity';
import { ConfigModule, ConfigService } from '@nestjs/config';

export const mysqlConfig: TypeOrmModuleAsyncOptions = {
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get<string>('DB_HOST'),
    port: configService.get<number>('DB_PORT'),
    username: configService.get<string>('DB_USERNAME'),
    password: configService.get<string>('DB_PASSWORD'),
    database: configService.get<string>('DB_DATABASE'),
    entities: [__dirname + '../**/*.entity{.ts,.js}'],
    synchronize: true,
    autoLoadEntities: true,
  }),
  inject: [ConfigService],
};

export const entities: EntityClassOrSchema[] = [User];

.env 环境变量如下配置,和config中对应上即可

DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=test
DB_PASSWORD=test
DB_DATABASE=test

日志

我使用的是nest-winston

1.安装

winston-daily-rotate-file 是用来每天生成的辅助

 npm i nest-winston winston winston-daily-rotate-file --save

2.创建配置文件

创建一个自己的winston配置文件 winston.config.ts

为了方便日志查看追踪,这里将timestamp进行了格式化,对应当前东八区时间

import {
  utilities as nestWinstonModuleUtilities,
  WinstonModuleOptions,
} from 'nest-winston';
import * as winston from 'winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';

const timeZone = 'Asia/Shanghai';

// 自定义时间格式化函数,东八区
const timestampFormat = () => {
  return new Date().toLocaleString('zh-CN', { timeZone });
};

export const winstonConfig: WinstonModuleOptions = {
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.timestamp({ format: timestampFormat }),
        nestWinstonModuleUtilities.format.nestLike('NestJS', {
          prettyPrint: true,
        }),
      ),
    }),
    // 配置其他transports(如文件日志)的示例
    new DailyRotateFile({
      filename: './logs/%DATE%_error.log',
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true, // 是否压缩旧文件
      maxSize: '20m',
      maxFiles: '14d', // 保留最近14天的日志
      level: 'error',
      format: winston.format.combine(
        winston.format.timestamp({ format: timestampFormat }),
        winston.format.printf(
          (info) => `${info.timestamp} ${info.level}: ${info.message}`,
        ),
      ),
    }),
    new DailyRotateFile({
      filename: './logs/%DATE%_info.log',
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true, // 是否压缩旧文件
      maxSize: '20m',
      maxFiles: '14d', // 保留最近14天的日志
      level: 'info',
      format: winston.format.combine(
        winston.format.timestamp({ format: timestampFormat }),
        winston.format.printf(
          (info) => `${info.timestamp} ${info.level}: ${info.message}`,
        ),
      ),
    }),
  ],
};

3.AppModule引入

import { WinstonModule } from 'nest-winston';
import { winstonConfig } from './configs/winston.config';

  imports: [
    WinstonModule.forRoot(winstonConfig),
    ...]

完结撒花 ❀❀❀❀❀