Skip to content

审计日志机制

什么是审计日志?

审计日志(也称为审计跟踪)是一个与安全相关的时间顺序记录、记录集和/或记录的目的地与来源,它为在任何时候影响特定操作、程序或事件的活动序列提供文件证据。

审计日志

在 NuxSaaS 中,审计日志对于跟踪用户活动、系统事件和潜在安全事件至关重要。它们有助于维护 accountability 、促进调试和确保合规性。

审计日志模式

审计日志条目存储在 audit_log 表中,其结构如下(定义在 server/database/schema/auditLog.ts):

  • id: SERIAL - 审计日志条目的唯一标识符(主键)。
  • userId: UUID - 执行操作的用户的 ID。这引用了 user.id。如果操作由系统或未经身份验证的实体执行,则可以为 null
  • category: TEXT - 事件的类别。示例:authemailpayment
  • action: TEXT - 执行的具体操作。示例:loginregisterverificationreset_passwordtrial_startsubscription_created
  • targetType: TEXT - 操作所针对的实体类型。示例:useremailstripeCustomerId
  • targetId: TEXT - 目标实体的标识符。
  • ipAddress: TEXT - 操作源的 IP 地址。
  • userAgent: TEXT - 发起操作的客户端的用户代理字符串。
  • status: TEXT - 操作的状态。示例:successfailurepending。默认为 success
  • details: TEXT - 与事件相关的其他详细信息或错误消息。
  • createdAt: TIMESTAMP - 事件发生时的时间戳。默认为当前时间。

审计事件是如何记录的

审计事件使用位于 server/utils/auditLogger.ts 中的 logAuditEvent 函数进行记录。这个集中式函数从应用程序的各个部分调用,以记录重要事件。

typescript
export async function logAuditEvent(data: {
  userId?: string;
  category: 'auth' | 'email' | 'payment';
  action: string;
  targetType?: string;
  targetId?: string;
  ipAddress?: string;
  userAgent?: string;
  status?: 'success' | 'failure' | 'pending';
  details?: string;
}) {
  // ...  将日志插入 audit_log 表的实现 ...
}

此函数接收一个包含事件详细信息的对象,并将其持久化到数据库中。

记录事件示例

NuxSaaS 在不同模块中记录各种事件:

1. 认证事件

与身份验证相关的活动通过 better-auth 系统中的钩子记录,如 server/utils/auth.ts 中所配置。

  • 记录的事件:
    • 用户登录尝试(例如 /sign-in/email
    • 用户注册(例如 /sign-up/email
    • 忘记密码请求(例如 /forget-password
    • 密码重置完成(例如 /reset-password
  • 捕获的信息:
    • userId(如果可用,例如,在成功登录后或对于现有会话操作)
    • category : auth
    • action : 认证操作的 API 路径(例如 /sign-in/email)。
    • targetType: email(用于电子邮件/密码操作)或 user
    • targetId: 用户的电子邮件或用户 ID。
    • ipAddress: 从请求头中捕获。
    • userAgent: 从请求头中捕获。
    • status: successfailure
    • details: 失败时的错误消息(例如,来自 APIError)。

2. 邮件发送事件

与发送邮件相关的事件(例如,验证、密码重置)在尝试发送邮件后直接记录。

  • 记录的事件(来自 server/utils/auth.ts):
    • 发送密码重置邮件(sendResetPassword 函数)。
    • 发送邮件验证邮件(sendVerificationEmail 函数)。
  • 捕获的信息
    • userId: 邮件发送对象的用户 ID。
    • category: email
    • action: reset_passwordverification
    • targetType: email
    • targetId: 用户的电子邮件地址。
    • status: successfailure(基于邮件发送服务响应)。
    • details: 邮件发送失败时的错误消息。

3. 支付事件(Stripe 集成)

支付和订阅生命周期事件通过 Stripe 集成的回调记录,如 server/utils/stripe.ts 中所定义。

  • 记录的事件
    • 试用开始 (trial_start)
    • 试用结束 (trial_end)
    • 试用期结束未转换 (trial_expired)
    • 订阅创建 (subscription_created)
    • 订阅更新 (subscription_updated)
    • 订阅取消 (subscription_canceled)
    • 订阅删除 (subscription_deleted)
  • 捕获的信息(由 addPaymentLog 辅助函数捕获):
    • userId: 与 Stripe 客户 ID 关联的用户 ID。
    • category: payment
    • action: 类似 trial_start:pro-monthly 的复合字符串,指示事件和计划。
    • targetType: stripeCustomerId
    • targetId: Stripe 客户 ID。
    • status: 对于这些由 webhook 驱动的事件,通常为 success

访问和使用审计日志

可以通过查询数据库中的 audit_log 表来访问审计日志。管理员可以将这些数据用于:

  • 安全监控:检测可疑活动、未经授权的访问尝试或潜在的安全漏洞。
  • 故障排除:通过审查导致问题的事件序列来诊断问题。
  • 合规性:为监管或内部合规性要求提供系统活动的证据。
  • 用户支持:了解用户操作以提供更好的帮助。

通常,管理面板中的专用界面将用于查看、筛选和搜索审计日志,使其易于管理。