@saihu/common
v1.5.5
Published
Common utilities for NestJS applications
Readme
Common
A collection of common utilities for NestJS applications, including permission guards, operation logging, and other helper utilities.
Installation
npm install @saihu/common权限与日志记录组件
PermissionGuard
PermissionGuard 是一个基于 NestJS 的权限守卫,用于验证用户是否有权限访问特定接口。它支持角色验证和权限验证两种方式。
依赖服务
- redis
功能特点
- 支持基于角色(Roles)的权限验证
- 支持基于权限(Perms)的细粒度权限验证
- 支持公共接口标记
- 可配置启用/禁用
使用装饰器
PermissionGuard 通过以下装饰器来定义接口的权限要求:
// 标记接口为公共接口,无需登录即可访问
@Public()
// 定义接口需要的角色
@Roles(['admin', 'editor'])
// 定义接口需要的权限
@Perms(['user:read', 'user:write'])配置选项
在 CommonModuleOptions 中可以配置 PermissionGuard 的行为:
interface CommonModuleOptions {
// 是否开启权限校验,默认为 true
usePerms?: boolean;
// 其他配置...
}使用示例
首先在模块中注册 CommonModule:
import { Module } from '@nestjs/common';
import { SaihuCommonModule } from '@saihu/common';
@Module({
imports: [
SaihuCommonModule.forRoot({
name: 'your-app-name',
usePerms: true, // 启用权限校验
// 其他配置...
}),
],
})
export class AppModule {}然后在控制器中使用装饰器:
import { Controller, Get } from '@nestjs/common';
import { Public, Roles, Perms } from '@saihu/common';
@Controller('users')
@UseGuards(AuthGuard, PermissionGuard)
export class UserController {
// 公共接口,无需登录
@Public()
@Get('public')
getPublicData() {
return { message: 'This is public data' };
}
// 需要 admin 或 editor 角色
@Roles(['admin', 'editor'])
@Get('admin')
getAdminData() {
return { message: 'This is admin data' };
}
// 需要 user:read 权限
@Perms(['user:read'])
@Get(':id')
getUserById() {
return { message: 'User data' };
}
}OperlogInterceptor
OperlogInterceptor 是一个操作日志拦截器,用于自动记录用户的操作行为,包括请求参数、响应结果、执行时间等信息。它会将日志通过 RabbitMQ 发送到消息队列。
功能特点
- 自动记录 HTTP 请求的详细信息
- 支持白名单配置,可以排除特定 URL
- 记录用户信息、IP 地址、请求参数、响应结果等
- 记录请求处理时间
- 通过 RabbitMQ 异步发送日志
配置选项
在 CommonModuleOptions 中可以配置 OperlogInterceptor 的行为:
interface CommonModuleOptions {
// 模块名称,会作为日志标题
name: string;
// 是否开启操作日志,默认为 true
useOperlog?: boolean;
// 操作日志白名单,符合条件的 URL 不会被记录
operlogWhitelist?: string[];
// RabbitMQ 配置
rabbitmq?: {
url: string;
};
// 其他配置...
}使用示例
在模块中注册 SaihuCommonModule 时配置操作日志:
import { Module } from '@nestjs/common';
import { SaihuCommonModule } from '@saihu/common';
@Module({
imports: [
SaihuCommonModule.forRoot({
name: 'your-app-name',
useOperlog: true, // 启用操作日志
operlogWhitelist: ['/health', '/metrics'], // 排除健康检查和监控接口
rabbitmq: {
url: 'amqp://localhost:5672',
},
}),
],
})
export class AppModule {}日志内容
操作日志包含以下信息:
title: 应用名称method: 控制器方法名request_method: HTTP 请求方法user_agent: 用户代理oper_name: 操作人员名称dept_name: 部门名称oper_url: 请求 URLoper_ip: 客户端 IPoper_param: 请求参数json_result: 响应结果status: HTTP 状态码error_msg: 错误信息(如有)oper_time: 操作时间cost_time: 处理耗时
模块配置
SaihuCommonModule 支持两种配置方式:同步配置和异步配置。
同步配置
SaihuCommonModule.forRoot({
name: 'your-app-name',
usePerms: true,
useOperlog: true,
operlogWhitelist: ['/health'],
redis: {
url: 'redis://localhost:6379',
password: 'your-redis-password',
},
rabbitmq: {
url: 'amqp://localhost:5672',
},
});异步配置
SaihuCommonModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
name: configService.get('APP_NAME'),
operlogWhitelist: configService.get('OPERLOG_WHITELIST')?.split(',') || [],
redis: {
url: configService.get('REDIS_URL'),
password: configService.get('REDIS_PASSWORD')
},
rabbitmq: {
url: configService.get('RABBITMQ_URL')
}
}),
inject: [ConfigService],
// 需要额外注册全局的APP_INTERCEPTOR
SaihuCommonModule.withOperlogInterceptor()
})