@sourceloop /审计服务
概述
这个 @sourceloop/audit-service 是一个功能强大的微服务,专为管理审计日志而设计。它提供了广泛的功能来跟踪和记录用户操作,如插入、更新和删除。建立在…的基础上 @sourceloop /审计日志,该服务提供了一个存储库mixin,便于集成。
默认情况下,存储库mixin记录所有操作,而审计服务将自定义提升到一个新的水平。它允许您有选择地审计特定的场景或案例,使您能够完全控制审计过程。使用服务公开的api,您可以毫不费力地插入和检索审计数据,使您能够根据自己的独特需求定制审计方法。
此外,审计服务通过提供归档特性,超越了基本功能。此功能允许您基于特定过滤器无缝地将日志归档到AWS S3桶中。您甚至可以同时从S3存储桶和审计数据库中检索日志,从而提供审计历史的全面视图。
安装
npm i @sourceloop/audit-service
开始使用
你可以开始使用 @sourceloop/audit-service 只需4步:
绑定组件
绑定 AuditServiceComponent 对于您的应用程序构造函数,如下所示,这将加载应用程序中此服务提供的所有控制器、存储库或任何其他工件以供使用。
import {AuditServiceComponent} from '@sourceloop/audit-service';
// ...
export class MyApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
) {
constructor(options: ApplicationConfig = {}) {
// ...
this.component(AuditServiceComponent);
}
}
非对称令牌签名和验证
如果您正在使用非对称令牌签名和验证,则应该在服务中提供认证数据源,并在facade级别上提供认证数据源。auth数据库的数据源文件示例为:-
验证DB数据源:-
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
import {AuthDbSourceName} from '@sourceloop/core';
const DEFAULT_MAX_CONNECTIONS = 25;
const DEFAULT_DB_IDLE_TIMEOUT_MILLIS = 60000;
const DEFAULT_DB_CONNECTION_TIMEOUT_MILLIS = 2000;
const config = {
name: 'auth',
connector: 'postgresql',
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
schema: process.env.DB_SCHEMA,
password: process.env.DB_PASSWORD,
database: process.env.AUTH_DB,
};
// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
@lifeCycleObserver('datasource')
export class AuthDataSource
extends juggler.DataSource
implements LifeCycleObserver
{
static dataSourceName = AuthDbSourceName;
static readonly defaultConfig = config;
constructor(
@inject('datasources.config.auth', {optional: true})
dsConfig: object = config,
) {
if (!!+(process.env.ENABLE_DB_CONNECTION_POOLING ?? 0)) {
const dbPool = {
max: +(process.env.DB_MAX_CONNECTIONS ?? DEFAULT_MAX_CONNECTIONS),
idleTimeoutMillis: +(
process.env.DB_IDLE_TIMEOUT_MILLIS ?? DEFAULT_DB_IDLE_TIMEOUT_MILLIS
),
connectionTimeoutMillis: +(
process.env.DB_CONNECTION_TIMEOUT_MILLIS ??
DEFAULT_DB_CONNECTION_TIMEOUT_MILLIS
),
};
dsConfig = {...dsConfig, ...dbPool};
}
super(dsConfig);
}
}
验证Cache Redis数据源:-
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {AnyObject, juggler} from '@loopback/repository';
import {readFileSync} from 'fs';
import {AuthCacheSourceName} from '@sourceloop/core';
const config = {
name: process.env.REDIS_NAME,
connector: 'kv-redis',
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
db: process.env.REDIS_DATABASE,
url: process.env.REDIS_URL,
tls:
+process.env.REDIS_TLS_ENABLED! && process.env.REDIS_TLS_CERT
? {
ca: readFileSync(process.env.REDIS_TLS_CERT),
}
: undefined,
sentinels:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINELS
? JSON.parse(process.env.REDIS_SENTINELS)
: undefined,
sentinelPassword:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_PASSWORD
? process.env.REDIS_SENTINEL_PASSWORD
: undefined,
role:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_ROLE
? process.env.REDIS_SENTINEL_ROLE
: undefined,
};
@lifeCycleObserver('datasource')
export class RedisDataSource
extends juggler.DataSource
implements LifeCycleObserver
{
static readonly dataSourceName = AuthCacheSourceName;
static readonly defaultConfig = config;
constructor(
@inject(`datasources.config.${process.env.REDIS_NAME}`, {optional: true})
dsConfig: AnyObject = config,
) {
if (
+process.env.REDIS_HAS_SENTINELS! &&
!!process.env.REDIS_SENTINEL_HOST &&
!!process.env.REDIS_SENTINEL_PORT
) {
dsConfig.sentinels = [
{
host: process.env.REDIS_SENTINEL_HOST,
port: +process.env.REDIS_SENTINEL_PORT,
},
];
}
super(dsConfig);
}
}
设置 环境变量
下面的示例显示了本地运行的PostgreSQL数据库的常见配置。
NODE_ENV=dev
LOG_LEVEL=DEBUG
HOST=0.0.0.0
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_USER=pg_service_user
DB_PASSWORD=pg_service_user_password
DB_DATABASE=audit_db
DB_SCHEMA=public
JWT_SECRET=super_secret_string
JWT_ISSUER=https://authentication.service
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
AWS_S3_BUCKET_NAME=
PATH_TO_EXPORT_FILES_FOLDER=
PATH_TO_UPLOAD_FILES=
配置数据源
建立一个 LoopBack4数据源 与 dataSourceName 属性设置为 AuditDbSourceName.
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
import {AuditDbSourceName} from '@sourceloop/audit-log';
const config = {
name: AuditDbSourceName,
connector: 'postgresql',
url: '',
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
schema: process.env.DB_SCHEMA,
};
@lifeCycleObserver('datasource')
export class AuditDbDataSource
extends juggler.DataSource
implements LifeCycleObserver
{
static dataSourceName = AuditDbSourceName;
static readonly defaultConfig = config;
constructor(
@inject(`datasources.config.${AuditDbSourceName}`, {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
迁移
此服务所需的迁移将在安装过程中自动处理 AUDIT_MIGRATION 或者 SOURCELOOP_MIGRATION env变量。迁移使用 db-migrate 与 db-migrate-pg 驱动程序,因此您必须安装这些包才能使用自动迁移。请注意,如果您正在使用一些预先存在的迁移或数据库,它们可能会受到影响。在这种情况下,建议您在项目根目录下复制迁移文件,使用 AUDIT_MIGRATION_COPY 或者 SOURCELOOP_MIGRATION_COPY env变量。您可以根据您的特定需求定制或挑选复制文件中的迁移,然后将它们应用到DB。
这个迁移脚本同时支持MySQL和PostgreSQL数据库,由环境变量控制。通过设置MYSQL_MIGRATION为“true”,脚本使用MySQL配置文件运行迁移;否则,默认为PostgreSQL。
此外,现在有一个选项可以选择SQL迁移或PostgreSQL迁移。
注:对于 @sourceloop/cli 用户可以在搭建过程中通过选择“数据源类型”选项来指定此选项。
使用
创建日志
此服务中的日志可以通过REST端点创建,也可以通过提供的存储库mixin创建 @sourceloop /审计日志 npm模块。默认情况下,这个mixin会为通过扩展存储库完成的所有内置操作创建日志。 您可以阅读有关如何使用此包的更多信息 在这里.
记录的所有不同类型的操作是:
export declare enum Action {
INSERT_ONE = 'INSERT_ONE',
INSERT_MANY = 'INSERT_MANY',
UPDATE_ONE = 'UPDATE_ONE',
UPDATE_MANY = 'UPDATE_MANY',
DELETE_ONE = 'DELETE_ONE',
DELETE_MANY = 'DELETE_MANY',
}
归档日志
审计日志可以通过REST端点进行归档 /audit-logs/archive. 一个 自定义过滤器 提供的,基于该日志可以归档。目前,它支持将归档日志上传到s3,您需要为此设置AWS凭据。
档案过滤器
{
"date": {
"fromDate": "2023-06-09T05:20:55.097Z",
"toDate": "2023-06-09T05:20:55.097Z"
},
//date parameter allows user to archive data from a given date to a given date
"deleted": true,
//deleted flag repesents the 'deleted' property of the 'after' column
"entityId": "string",
//entityId represents the unique id of a particular entities
"actedOn": "Product"
//actedOn represents the model class for which audit logs are generated
}
档案的反应
在请求存档后,您将得到类似的响应:
{
"message": "Entries archived successfully",
"numberOfEntriesArchived": 1,
"key": "audit_logs_2023-06-09T05:44:24.780Z.csv"
}
在这里 key 代表的 AWS S3对象密钥 包含存档日志的文件的。
归档审计日志
这提供了一个函数,用于将所选数据转换为csv格式,并将其导出到变量中指定的AWS S3桶中 AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,AWS_REGION,AWS_S3_BUCKET_NAME 的变量 env 文件。默认情况下,文件在AWS S3桶上以csv格式导出,可以使用此提供程序覆盖该桶。这些值也可以在配置文件中提供。也有必要提供的价值PATH_TO_UPLOAD_FILES 的变量 env 文件。配置文件可以在应用程序中绑定
this.bind(AWSS3Bindings.Config).to({
accessKeyId: '', // Replace with your actual access key
secretAccessKey: '', // Replace with your actual secret access key
region: '', // Replace with your desired AWS region
} as AwsS3Config);
this.bind(ExportToCsvServiceBindings.EXPORT_LOGS.key).toProvider(
ExportToCsvProvider,
);
可以看到它的实现 在这里
获取日志
该特性用于查询审计数据库或归档存储(例如。AWS S3)。接受一个自错环回过滤器,根据该过滤器可以提取日志。与此同时还有一个布尔变量叫做 includeArchivedLogs 还提供哪些接受 true 或者 false 导致是否在响应中包含已归档的日志。
如果 includeArchivedLogs 设为 true 将根据作为输入提供的过滤器从审计数据库和存档存储中获取数据 但它不会立即归还,一个 jobId 返回,它表示在后台从归档存储中获取和解析日志的操作。这 jobId 可用于检查此进程的状态,并在完成时获得结果。
如果 includeArchivedLogs 选项设置为 false (如果没有提供,这是默认值)数据只从审计数据库而不是从归档存储中获取,在这种情况下,响应包含请求的数据。
导出日志
此功能用于导出审计数据库或归档存储(例如。AWS.S3)。接受默认的环回过滤器,根据该过滤器将日志导出到指定的位置,如excel文件(默认情况下)使用 AuditLogExportProvider 在这里.
类使用的exceljs依赖项 AuditLogExportProvider 用于生成Excel文件,是可选的。希望使用此功能的用户应该手动安装exceljs并在应用程序中绑定AuditLogExportProvider。你的申请:
this.bind(AuditLogExportServiceBindings.EXPORT_AUDIT_LOGS).toProvider(
AuditLogExportProvider,
);
通过遵循这些步骤,用户可以无缝地将AuditLogExportProvider合并到他们的应用程序中,同时可以灵活地选择是否包含exceljs依赖项。
与此同时还有一个布尔变量叫做 includeArchivedLogs 还提供哪些接受 true 或者 false 导致是否在响应中包含已归档的日志。
如果 includeArchivedLogs 设为 true 然后,将根据作为输入提供的过滤器从审计数据库和存档存储中获取数据 但它不会立即归还,一个 jobId 返回,它表示在后台从归档存储中获取和解析日志的操作。这 jobId 可用于检查此进程的状态,并在完成时获得结果。
如果 includeArchivedLogs 选项设置为 false (如果没有提供,这是默认值)数据只从审计数据库而不是从归档存储中获取,在这种情况下,响应包含请求的数据。
该特性还允许为数据提供自定义列名,或将特定列组合在一起。这可以在提供者的帮助下完成,提供者可以被覆盖,如下所述
创建自定义列
它提供了一个函数,用于自定义原始数据中的列。自定义列的名称也可以在函数中指定。默认情况下,不对原始数据进行任何更改。为了进行所需的更改,提供程序可以覆盖如下所示的更改。
示例实现- - - - - -
此键的提供程序用于创建自定义列和自定义列名
this.bind(ColumnBuilderServiceBindings.COLUMN_BUILDER.key).toProvider(
ColumnBuilderProvider,
);
export class ColumnBuilderProvider implements Provider<ColumnBuilderFn> {
constructor() {}
value(): ColumnBuilderFn {
return async (auditLogs: AuditLog[]) => {
return this.columnBuilder(auditLogs);
};
}
async columnBuilder(auditLogs: AuditLog[]): Promise<AnyObject[]> {
return auditLogs.map(log => ({
beforeAfterCombined: `${JSON.stringify(log.before)} ${JSON.stringify(
log.after,
)}`,
actedOnActionCombined: `${log.actedOn} ${log.actionKey}`,
}));
}
}
流程审计日志
这提供了一个函数,它将excel文件缓冲区作为输入,并可以在excel文件缓冲区上执行任何所需的操作。
this.bind(ExportHandlerServiceBindings.PROCESS_FILE.key).toProvider(
ExportHandlerProvider,
);
可以看到它的实现 在这里
环境变量
| 名字 | 要求 | 默认值 | 描述 |
|---|---|---|---|
NODE_ENV |
Y | 节点环境值,即 dev, test, prod |
|
LOG_LEVEL |
Y | 日志级别值,即 error, warn, info, verbose, debug |
|
DB_HOST |
Y | 数据库服务器的主机名。 | |
DB_PORT |
Y | 数据库服务器的端口。 | |
DB_USER |
Y | 数据库的用户。 | |
DB_PASSWORD |
Y | 数据库用户的密码。 | |
DB_DATABASE |
Y | 数据库服务器上要连接的数据库。 | |
DB_SCHEMA |
Y | public |
用于数据源的数据库模式。在PostgreSQL中,这将是 public 除非为服务显式地制定了模式。 |
JWT_SECRET |
Y | JWT令牌的对称签名密钥。 | |
JWT_ISSUER |
Y | JWT令牌的发行者。 | |
AWS_ACCESS_KEY_ID |
N | 与您的AWS帐户关联的访问密钥ID | |
AWS_SECRET_ACCESS_KEY |
N | 与您的AWS账户关联的秘密访问密钥。 | |
AWS_REGION |
N | 指定您的AWS S3桶所在的AWS区域。 | |
AWS_S3_BUCKET_NAME |
N | 归档审计日志存放的AWS S3桶名。 | |
PATH_TO_EXPORT_FILES_FOLDER |
N | 导出文件的存放路径。 | |
PATH_TO_UPLOAD_FILES |
N | S3桶存放归档文件的路径。 |
与Sequelize一起使用
此服务支持Sequelize作为底层ORM使用 @loopback / sequelize 扩展。为了使用它,您需要做以下更改。
1.要在应用程序中使用Sequelize,请在application.ts中添加以下内容:
this.bind(AuditServiceBindings.Config).to({
useCustomSequence: false,
useSequelize: true,
});
- 使用
SequelizeDataSource在审计数据源中作为父类。参考 这 更多信息。
API文档
常见的头
授权:承载,其中是使用JWT颁发者和密钥签名的JWT令牌。
Content-Type: application/json 如果API方法不是GET,则在响应和请求中。
API的细节
参观 OpenAPI规范文档 以获取有关此服务中提供的api的更多详细信息。
许可证
Sourceloop是 麻省理工学院的许可.
