---
title: "Auth0 连接器"
description: "完整的 Auth0 集成指南，通过 Tajo 将用户认证数据、身份档案和访问事件与 Brevo 同步。"
url: https://tajo.io/zh-cn/docs/connectors/custom/auth0/
markdown: https://tajo.io/zh-cn/docs/connectors/custom/auth0.md
lang: zh-CN
robots: noindex
---

申请抢先体验

请输入您的名字和公司电子邮箱地址。我们会发送确认 Tajo 访问申请的链接。

# Auth0 连接器

连接器状态: 计划中 尚未构建。Tajo 目前不运行此连接器。

| 来源字段 | 目标字段 | 示例值 |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

通过 Tajo 将 Auth0 连接到 Brevo，将已认证的用户档案同步为营销联系人，根据认证事件触发自动化，并以身份和访问管理洞察丰富您的客户数据。

## 概览

| 属性 | 值 |
| --- | --- |
| **平台** | Auth0（by Okta） |
| **类别** | 身份与访问（自定义） |
| **设置复杂度** | 中等 |
| **官方集成** | 否 |
| **同步数据** | 用户、事件、角色、身份 |
| **认证方式** | 机器对机器 OAuth 2.0 |

## 功能

- **用户档案同步** - 将 Auth0 用户档案同步到 Brevo 联系人
- **认证事件** - 在登录、注册和密码重置时触发自动化
- **基于角色的细分** - 根据 Auth0 角色和权限细分联系人
- **社交身份数据** - 用社交登录档案信息丰富联系人
- **登录活动跟踪** - 跟踪最后登录、登录次数和设备数据
- **多租户支持** - 跨多个 Auth0 租户同步用户

## 前提条件

开始之前，请确保您已具备：

1. 具有 API 访问权限的 Auth0 账户
2. 在 Auth0 中注册的机器对机器应用
3. 授予 M2M 应用的管理 API 权限
4. 具有 API 访问权限的 Brevo 账户
5. 具有连接器权限的 Tajo 账户

## 认证

### 机器对机器 OAuth 2.0

```bash
# Create an M2M application in Auth0 Dashboard
export AUTH0_DOMAIN=your-tenant.auth0.com
export AUTH0_CLIENT_ID=your_client_id
export AUTH0_CLIENT_SECRET=your_client_secret
export AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
```

```javascript
// Get Management API access token
const tokenResponse = await fetch(
  `https://${process.env.AUTH0_DOMAIN}/oauth/token`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      client_id: process.env.AUTH0_CLIENT_ID,
      client_secret: process.env.AUTH0_CLIENT_SECRET,
      audience: process.env.AUTH0_AUDIENCE,
      grant_type: 'client_credentials'
    })
  }
);

const { access_token } = await tokenResponse.json();
// Token is valid for 24 hours by default
```

API 权限

仅向您的 M2M 应用授予所需范围：`read:users`、`read:user_idp_tokens`、`read:roles` 和 `read:logs`。非必要不授予写入权限。

## 配置

### 基础设置

```yaml
connectors:
  auth0:
    enabled: true
    domain: "${AUTH0_DOMAIN}"
    client_id: "${AUTH0_CLIENT_ID}"
    client_secret: "${AUTH0_CLIENT_SECRET}"
    audience: "https://${AUTH0_DOMAIN}/api/v2/"

    sync:
      users: true
      events: true
      roles: true
      schedule: "0 */4 * * *"  # Every 4 hours

    lists:
      all_users: 20
      verified_users: 21
      social_login: 22
```

### 字段映射

```yaml
field_mapping:
  email: email
  given_name: FIRSTNAME
  family_name: LASTNAME
  nickname: NICKNAME
  picture: AVATAR_URL
  email_verified: EMAIL_VERIFIED
  logins_count: LOGIN_COUNT
  last_login: LAST_LOGIN_DATE
  created_at: SIGNUP_DATE
  user_metadata.phone: SMS
  user_metadata.company: COMPANY
  app_metadata.plan: SUBSCRIPTION_PLAN
  app_metadata.role: USER_ROLE
```

## API 端点

| 端点 | 方法 | 描述 |
| --- | --- | --- |
| `https://{domain}/api/v2/users` | GET | 列出或搜索用户 |
| `https://{domain}/api/v2/users/{id}` | GET | 获取用户 |
| `https://{domain}/api/v2/users/{id}` | PATCH | 更新用户元数据 |
| `https://{domain}/api/v2/users/{id}/roles` | GET | 获取用户角色 |
| `https://{domain}/api/v2/roles` | GET | 列出所有角色 |
| `https://{domain}/api/v2/logs` | GET | 获取日志事件 |
| `https://{domain}/api/v2/stats/active-users` | GET | 获取活跃用户数 |
| `https://{domain}/api/v2/stats/daily` | GET | 获取每日统计 |
| `https://{domain}/oauth/token` | POST | 获取访问令牌 |

## 代码示例

### 初始化连接器

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('auth0', {
  domain: process.env.AUTH0_DOMAIN,
  clientId: process.env.AUTH0_CLIENT_ID,
  clientSecret: process.env.AUTH0_CLIENT_SECRET
});
```

### 将用户同步到 Brevo

```javascript
// Paginate through Auth0 users
let page = 0;
const perPage = 50;
let hasMore = true;

while (hasMore) {
  const response = await fetch(
    `https://${domain}/api/v2/users?` +
      new URLSearchParams({
        page: page.toString(),
        per_page: perPage.toString(),
        include_totals: 'true',
        search_engine: 'v3',
        q: 'email_verified:true'
      }),
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );

  const { users, total } = await response.json();

  for (const user of users) {
    await tajo.contacts.sync({
      email: user.email,
      attributes: {
        FIRSTNAME: user.given_name,
        LASTNAME: user.family_name,
        LOGIN_COUNT: user.logins_count,
        LAST_LOGIN_DATE: user.last_login,
        SIGNUP_DATE: user.created_at,
        EMAIL_VERIFIED: user.email_verified
      },
      listIds: [20]
    });
  }

  page++;
  hasMore = (page * perPage) < total;
}
```

### 通过日志流跟踪认证事件

```javascript
// Set up Auth0 Log Stream webhook
// Configure in Auth0 Dashboard > Monitoring > Streams

app.post('/webhooks/auth0', async (req, res) => {
  // Verify authorization header
  const authHeader = req.headers.authorization;
  if (authHeader !== `Bearer ${process.env.AUTH0_WEBHOOK_TOKEN}`) {
    return res.status(401).send('Unauthorized');
  }

  const logs = req.body;

  for (const log of logs) {
    switch (log.data.type) {
      case 's':   // Successful login
        await tajo.events.track({
          email: log.data.details.email,
          event: 'user_login',
          properties: {
            ip: log.data.ip,
            user_agent: log.data.user_agent,
            connection: log.data.connection
          }
        });
        break;
      case 'ss':  // Successful signup
        await tajo.contacts.sync({
          email: log.data.details.email,
          attributes: { SIGNUP_DATE: log.data.date },
          listIds: [20]
        });
        break;
      case 'sp':  // Successful password change
        await tajo.events.track({
          email: log.data.details.email,
          event: 'password_changed'
        });
        break;
    }
  }

  res.status(200).send('OK');
});
```

### 基于角色的细分

```javascript
// Sync user roles for segmentation
const rolesResponse = await fetch(
  `https://${domain}/api/v2/users/${userId}/roles`,
  {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);

const roles = await rolesResponse.json();
const roleNames = roles.map(r => r.name).join(', ');

await tajo.contacts.update(userEmail, {
  attributes: {
    USER_ROLE: roleNames,
    IS_ADMIN: roles.some(r => r.name === 'admin')
  }
});
```

## 速率限制

| 端点类别 | 限制 | 说明 |
| --- | --- | --- |
| 管理 API | 50 请求/秒（免费） | 每租户 |
| 管理 API | 100 请求/秒（付费） | 每租户 |
| 认证 API | 因计划而异 | 基于计划 |
| 日志流 | 实时 | 投递无速率限制 |
| 分页 | 每页最多 50 条 | 使用 `page` 和 `per_page` 参数 |

需要分页

Auth0 管理 API 每页最多返回 50 条结果。始终使用 `page` 和 `per_page` 参数实现分页。包含 `include_totals=true` 以获取总数。

## 故障排除

| 问题 | 原因 | 解决方案 |
| --- | --- | --- |
| 401 Unauthorized | 令牌已过期 | 请求新的 M2M 令牌（24 小时有效期） |
| 403 Forbidden | 缺少范围 | 向 M2M 应用授予所需权限 |
| 用户列表为空 | 搜索查询错误 | 使用 v3 引擎的 Lucene 查询语法 |
| 元数据缺失 | 未设置元数据 | 检查 user\_metadata 和 app\_metadata |
| 速率限制 429 | 请求过多 | 使用重试头实现退避 |

### 调试模式

```yaml
connectors:
  auth0:
    debug: true
    log_level: verbose
    log_sync: true
```

## 最佳实践

1. **使用日志流** - 实时事件流而非轮询日志 API
2. **实施分页** - 始终对大型租户的用户列表查询进行分页
3. **缓存 M2M 令牌** - 在接近过期前复用令牌（默认 24 小时有效期）
4. **使用搜索引擎 v3** - 使用 Lucene 查询语法高效搜索用户
5. **仅同步已验证用户** - 过滤 `email_verified:true` 以避免未验证联系人
6. **利用用户元数据** - 在 Auth0 user\_metadata 中存储自定义属性以便同步

## 安全

- **机器对机器 OAuth** - 服务器到服务器认证的客户端凭据授权
- **范围权限** - 授予最低所需管理 API 范围
- **令牌轮换** - M2M 令牌默认 24 小时后过期
- **日志流认证** - 使用 Bearer 令牌验证 Webhook 端点
- **租户隔离** - 每个 Auth0 租户单独配置
- **加密传输** - 所有 API 通信使用 TLS 1.2+

## 相关资源

- [Segment 连接器](https://tajo.io/zh-cn/docs/connectors/custom/segment)
- [Zapier 连接器](https://tajo.io/zh-cn/docs/connectors/custom/zapier)
- [客户同步技能](https://tajo.io/zh-cn/docs/skills/data-sync/customer-sync)
- [Auth0 管理 API 文档](https://auth0.com/docs/api/management/v2)
