# 审计日志 (/docs/infrastructure/plugins/audit-logs)

通过自动审计日志记录，跟踪并查询应用中的身份验证事件。



Better Auth 基础设施会自动收集您应用中的身份验证事件审计日志。一旦您添加了 `dash()` 插件，事件即会在无需额外配置的情况下被追踪。

## 审计日志的收集方式 [#审计日志的收集方式]

`dash()` 插件会挂载到您的 Better Auth 实例中，自动记录发生的事件。无需手动插桩——注册、登录、密码更改等操作均会被捕获。

```ts
import { betterAuth } from "better-auth";
import { dash } from "@better-auth/infra";

export const auth = betterAuth({
  plugins: [
    dash(),
  ],
});
```

就这样。`dash()` 激活后，审计日志会自动被收集。

## 跟踪事件 [#跟踪事件]

<Tabs items="[&#x22;User&#x22;, &#x22;Session&#x22;, &#x22;Account&#x22;, &#x22;Verification&#x22;, &#x22;Organization&#x22;, &#x22;Security&#x22;]">
  <Tab value="User">
    | 事件                           | 触发条件     |
    | ---------------------------- | -------- |
    | `user_signed_up`             | 新用户注册    |
    | `user_profile_updated`       | 用户更新个人资料 |
    | `user_profile_image_updated` | 用户更改头像   |
    | `user_email_verified`        | 邮箱验证完成   |
    | `user_banned`                | 用户被封禁    |
    | `user_unbanned`              | 用户解封     |
    | `user_deleted`               | 用户账户删除   |
  </Tab>

  <Tab value="Session">
    | 事件                           | 触发条件      |
    | ---------------------------- | --------- |
    | `user_signed_in`             | 登录成功      |
    | `user_signed_out`            | 用户登出      |
    | `session_created`            | 新会话创建     |
    | `session_revoked`            | 单个会话被吊销   |
    | `sessions_revoked_all`       | 所有会话被吊销   |
    | `user_impersonated`          | 管理员开始模拟用户 |
    | `user_impersonation_stopped` | 管理员停止模拟   |
  </Tab>

  <Tab value="Account">
    | 事件                 | 触发条件     |
    | ------------------ | -------- |
    | `account_linked`   | 社交账户关联   |
    | `account_unlinked` | 社交账户取消关联 |
    | `password_changed` | 密码更新     |
  </Tab>

  <Tab value="Verification">
    | 事件                         | 触发条件    |
    | -------------------------- | ------- |
    | `password_reset_requested` | 密码重置已发起 |
    | `password_reset_completed` | 密码重置已完成 |
    | `email_verification_sent`  | 验证邮件已发送 |
  </Tab>

  <Tab value="Organization">
    在使用 [组织插件](/docs/plugins/organization) 时追踪。

    | 事件                     | 触发条件     |
    | ---------------------- | -------- |
    | `organization_created` | 新组织创建    |
    | `organization_updated` | 组织设置已更改  |
    | `member_added`         | 成员已添加到组织 |
    | `member_removed`       | 成员已从组织移除 |
    | `member_role_updated`  | 成员角色已更改  |
    | `member_invited`       | 邀请已发送    |
    | `invite_accepted`      | 邀请已接受    |
    | `invite_rejected`      | 邀请已拒绝    |
    | `invite_cancelled`     | 邀请已取消    |
    | `team_created`         | 团队已创建    |
    | `team_updated`         | 团队已更新    |
    | `team_deleted`         | 团队已删除    |
    | `team_member_added`    | 成员已添加到团队 |
    | `team_member_removed`  | 成员已从团队移除 |
  </Tab>

  <Tab value="Security">
    在使用 [Sentinel](/docs/infrastructure/plugins/sentinel) 插件时追踪。

    | 事件                              | 触发条件        |
    | ------------------------------- | ----------- |
    | `security_blocked`              | 请求已被阻止      |
    | `security_allowed`              | 请求在挑战后被允许   |
    | `security_credential_stuffing`  | 检测到凭证填充     |
    | `security_impossible_travel`    | 检测到不可能存在的旅行 |
    | `security_geo_blocked`          | 触发地理屏蔽      |
    | `security_bot_blocked`          | 检测到机器人并已阻止  |
    | `security_suspicious_ip`        | 检测到可疑 IP    |
    | `security_velocity_exceeded`    | 超出速率限制      |
    | `security_free_trial_abuse`     | 检测到免费试用滥用   |
    | `security_compromised_password` | 检测到泄露的密码    |
    | `security_stale_account`        | 陈旧账户重新激活    |
  </Tab>
</Tabs>

## 获取审计日志 [#获取审计日志]

### 客户端设置 [#客户端设置]

在您的认证客户端中添加 `dashClient()`：

```ts
import { createAuthClient } from "better-auth/client";
import { dashClient } from "@better-auth/infra/client";

export const authClient = createAuthClient({
  plugins: [dashClient()],
});
```

### 获取当前用户的审计日志 [#获取当前用户的审计日志]

返回 **当前用户** 的审计事件。用于终端用户活动以及调用方为普通成员的组织视图。

#### 查询参数 [#查询参数]

| 参数               | 类型       | 描述                  |
| ---------------- | -------- | ------------------- |
| `limit`          | `number` | 每页结果数（最大 100，默认 50） |
| `offset`         | `number` | 分页偏移量（默认 0）         |
| `organizationId` | `string` | 按组织筛选               |
| `identifier`     | `string` | 按标识符筛选              |
| `eventType`      | `string` | 按事件类型筛选             |
| `userId`         | `string` | 按用户 ID 筛选           |
| `user`           | `object` | 带有 ID 的用户对象         |
| `session`        | `object` | 带有用户的会话对象           |

#### 基本查询 [#基本查询]

```ts
const session = await authClient.getSession();

const logs = await authClient.dash.getAuditLogs({
  session: session.data,
  limit: 50,
  offset: 0,
});

logs.data?.events;  // 审计日志事件数组
logs.data?.total;   // 总数量
logs.data?.limit;   // 每页大小
logs.data?.offset;  // 当前偏移量
```

#### 按事件类型筛选 [#按事件类型筛选]

返回当前用户的登录审计日志。

```ts
const signIns = await authClient.dash.getAuditLogs({
  session: session.data,
  eventType: "user_signed_in",
});
```

#### 按组织筛选 [#按组织筛选]

返回当前用户在指定组织范围内的审计日志。

```ts
const orgLogs = await authClient.dash.getAuditLogs({
  session: session.data,
  organizationId: "org_123",
});
```

#### 组合筛选 [#组合筛选]

您可以组合筛选条件以获得更具体的结果（例如，当前用户在特定组织中的所有登录事件）。

```ts
const orgSignIns = await authClient.dash.getAuditLogs({
  session: session.data,
  organizationId: "org_123",
  eventType: "user_signed_in",
});
```

您也可以将结果限制为特定标识符（例如，当前用户在特定组织和邮箱下的所有事件）。

```ts
const orgSignIns = await authClient.dash.getAuditLogs({
  session: session.data,
  organizationId: "org_123",
  identifier: "user@example.com",
});
```

> **注意**：标识符是事件的唯一值。例如，电子邮件地址、用户名等。

#### 分页 [#分页]

结果是分页返回的。如果您需要获取多页内容，可以使用 `limit` 和 `offset` 参数对结果进行分页：

```ts
async function fetchAllUserAuditLogEvents(session: unknown) {
  const limit = 100;
  let offset = 0;
  const allEvents = [];

  while (true) {
    const result = await authClient.dash.getAuditLogs({
      session: session.data,
      limit,
      offset,
    });
    
    const events = result.data?.events ?? [];
    allEvents.push(...events);

    if (events.length < limit) break;
    offset += limit;
  }

  return allEvents;
}
```

### 获取全部审计日志 [#获取全部审计日志]

返回当前用户拥有 **管理员** 或 **所有者** 访问权限的组织的所有审计事件。用于需要跨您管理的组织查看活动的管理员式仪表盘。
您必须使用 [组织插件](/docs/plugins/organization)，以便评估成员角色。

#### 查询参数 [#查询参数-1]

| 参数               | 类型       | 描述                                    |
| ---------------- | -------- | ------------------------------------- |
| `limit`          | `number` | 每页结果数（最大 `100`，默认 `50`）               |
| `offset`         | `number` | 分页偏移量（默认 `0`）                         |
| `organizationId` | `string` | 将结果限制为一个组织（您必须是所有者或管理员）               |
| `userId`         | `string` | 限制为您以所有者或管理员身份管理的组织中某一用户的活动           |
| `eventType`      | `string` | 按事件类型筛选                               |
| `identifier`     | `string` | 匹配 `eventData.identifier`（组织范围内的主体标识） |
| `session`        | `object` | 带有用户的会话对象                             |

#### 基本查询 [#基本查询-1]

```ts
const session = await authClient.getSession();

const activity = await authClient.dash.getAllAuditLogs({
  session: session.data,
  limit: 50,
  offset: 0,
});

activity.data?.events;
activity.data?.total;
activity.data?.limit;
activity.data?.offset;
```

#### 按组织筛选 [#按组织筛选-1]

返回指定组织的所有审计事件：

```ts
const orgActivity = await authClient.dash.getAllAuditLogs({
  session: session.data,
  organizationId: "org_123",
});
```

#### 按用户筛选 [#按用户筛选]

返回跨组织的指定用户的所有审计事件：

```ts
const userActivity = await authClient.dash.getAllAuditLogs({
  session: session.data,
  userId: "user_456",
});
```

#### 按事件类型筛选 [#按事件类型筛选-1]

返回跨组织的指定事件类型的所有审计事件：

```ts
const events = await authClient.dash.getAllAuditLogs({
  session: session.data,
  eventType: "member_invited",
});
```

#### 组合筛选 [#组合筛选-1]

您可以组合筛选条件以获得更具体的结果（例如，指定组织和事件类型的所有审计事件）。

```ts
const orgEvents = await authClient.dash.getAllAuditLogs({
  session: session.data,
  organizationId: "org_123",
  eventType: "member_invited",
});
```

#### 分页 [#分页-1]

结果是分页返回的。如果您需要获取多页内容，可以使用 `limit` 和 `offset` 参数对结果进行分页：

```ts
async function fetchAllAuditLogs(session: unknown) {
  const limit = 100;
  let offset = 0;
  const allEvents = [];

  while (true) {
    const result = await authClient.dash.getAllAuditLogs({
      session: session.data,
      limit,
      offset,
    });
    
    const events = result.data?.events ?? [];
    allEvents.push(...events);

    if (events.length < limit) break;
    offset += limit;
  }

  return allEvents;
}
```

