揭秘Auth0 My Account API:让用户安全自主管理账户

本文详细介绍了Auth0新推出的My Account API,该API使开发者能够安全地在客户端实现用户自主管理账户功能,如注册通行密钥、管理关联账户等,从而简化了传统需要服务器端代理的复杂架构,提升了开发效率与用户体验。

Auth0 My Account API:让用户管理自己的账户

了解Auth0 My Account API如何安全地实现客户端的、自助式的用户管理,从而无需为通行密钥注册和账户关联等功能构建服务器端代理。

传统上,为了让用户管理自己的账户详情(例如更新个人信息、注册多因素认证或关联社交账户),开发者必须依赖Auth0管理API。由于管理API拥有广泛的管理权限,其令牌必须在服务器端组件中处理。这常常导致架构复杂,要求单页面应用或移动应用的开发者构建一个专门的后端代理,仅仅是为了促成简单的用户自助操作。这种复杂性带来了开发时间和API令牌管理开销方面的挑战。

My Account API旨在简化这些问题,提供合适的工具,即使是您的SPA或移动应用用户也能安全、直接地轻松管理自己的个人资料。这就是用户自助管理的精髓。

介绍My Account API

My Account API是一组专门为客户端自助服务设计的端点。该API完全在当前登录用户的上下文中运行。这是通过将所有API调用范围限定在特殊路径 /me 来实现的。

与需要高权限令牌的管理API不同,My Account API使用在标准用户登录过程中颁发的访问令牌。这些令牌必须使用特定的受众和一组作用域来请求。

这个设计选择是关键:该API本质上仅限于已认证用户的个人资料,使其可以安全地从公共客户端(如基于浏览器的React应用)直接调用,而不会危及整个租户的安全。

激活My Account API

在使用API之前,您必须在Auth0仪表板的“身份验证”>“API”下为您的租户激活它。将显示如下所示的横幅,您只需单击“激活”按钮:

这会将“Auth0 My Account API”项添加到API列表中。

要调用API,您需要使用在My Account API页面“设置”选项卡中可用的API标识符(受众)值。通常,它的形式为 https://YOUR_AUTH0_DOMAIN/me/

您还需要启用应用程序所需的作用域。转到“应用程序”选项卡,通过切换开关按钮为您的应用程序启用该API,展开作用域部分,并选择您想要启用的作用域:

作为一般规则,仅启用您的应用程序实际需要的作用域。单击“更新”按钮以保存更改。

在撰写本文时,MyAccount API处于有限早期访问阶段,因此您可能无法获得上面显示的所有作用域。请查阅文档以了解有关请求访问有限早期访问计划的更多信息。

作用域允许您的应用程序调用特定端点并使用特定的HTTP动词。例如,要允许用户注册新的通行密钥,您必须请求作用域 create:me:authentication-methods。其他作用域包括用于管理关联社交账户的 read:me:connected_accountsdelete:me:connected_accounts 等。

要获取My Account API的访问令牌,您将使用在用户登录时获取访问令牌的常用方法。您只需指定您的My Account API受众和所需的作用域。以下是My Account API授权请求的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
curl --request GET \
  --url 'https://YOUR_AUTH0_DOMAIN/authorize' \
  -d 'client_id=1234567890' \
  -d 'response_type=code' \
  -d 'redirect_uri=https://my-app.com/callback' \
  -d 'audience=https://YOUR_AUTH0_DOMAIN/me/' \
  -d 'scope=read:me:authentication-methods read:me:connected_accounts' \
  -d 'state=wo87trfgwcdf2' \
  -d 'nonce=dh9812hdd29' \
  -d 'code_challenge=p2g8guffhp9hf398yyhh328' \
  -d 'code_challenge_method=S256'

使用可用的Auth0身份验证SDK之一来验证您的应用程序用户并获取访问令牌。

直接调用API

为了理解基本的交互方式,查看与API接口所使用的原始HTTP请求是有帮助的,无论使用何种编程语言。所有直接调用都需要在Authorization标头中发送访问令牌。

以下cURL命令演示了如何读取用户当前已注册的身份验证方法:

1
2
3
4
curl --request GET \
  --url 'https://YOUR_AUTH0_DOMAIN/me/authentication-methods' \
  --header 'Authorization: Bearer USER_ACCESS_TOKEN' \
  --header 'Content-Type: application/json'

这个例子展示了如何使用Authorization标头中的承载访问令牌调用 authentication-methods 端点。基础URL必须使用为您的My Account API设置的受众,并且访问令牌必须具有 read:me:authentication-methods 作用域。

这是使用API实现客户端账户管理的基本方式。任何能够发出HTTP请求的应用程序都可以实现这种模式。

使用SDK简化API调用

对于基于JavaScript的应用程序,您可以利用专用的 myaccount-js SDK。该SDK抽象了原始的HTTP逻辑,简化了请求创建、参数处理和响应解析。

要在基于Node.js的开发环境中安装SDK,请运行以下命令:

1
npm install @auth0/myaccount-js

让我们探讨在两种场景下使用SDK的基本步骤:客户端和服务器端使用。

客户端SDK使用:React示例

在客户端SPA中,SDK非常适合在用户登录并获取访问令牌后使用。我们将在示例中使用React,但该SDK与框架无关,因此无论您的开发框架是什么,都可以使用它。

以下代码片段展示了如何轻松读取用户的关联账户:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { useState, useEffect } from 'react';
import { MyAccountClient, MyAccount } from '@auth0/myaccount-js';

function ConnectedAccountsManager({ getAccessTokenSilently, domain }) {
  const [accounts, setAccounts] = useState<MyAccount.ConnectedAccount[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchConnectedAccounts() {
      try {
        // 1. 获取具有必要作用域的访问令牌
        const token = await getAccessTokenSilently({
          authorizationParams: {
            audience: `https://${YOUR_AUTH0_DOMAIN}/me/`,
            scope: 'read:me:connected_accounts'
          },
        });

        // 2. 初始化MyAccount客户端
        const myAccountClient = new MyAccountClient({
          domain: domain,
          token: token
        });

        // 3. 使用SDK方法获取所有关联账户
        const connectedAccounts = await myAccountClient.connectedAccounts.list();
        setAccounts(connectedAccounts.data);
      } catch (error) {
        console.error('加载关联账户失败:', error);
      } finally {
        setLoading(false);
      }
    }
    fetchConnectedAccounts();
  }, [getAccessTokenSilently, domain]);

  // ... (组件渲染逻辑)
}

React组件 ConnectedAccountsManager 旨在渲染当前用户关联账户的列表。

它通过指定此次操作所需的受众和作用域,使用 getAccessTokenSilently() 函数获取访问令牌。然后,它使用域和获取到的令牌初始化由SDK提供的 myAccountClient 客户端。通过调用SDK的 myAccountClient.connectedAccounts.list() 方法,获取用户关联账户的列表。最后,该组件使用 accounts 状态来显示关联账户。

服务器端SDK使用:Node.js示例

myaccount-js SDK可以在服务器端JavaScript应用程序中使用,例如在Node.js环境中。

以下代码使用SDK以编程方式移除一个关联账户,这需要 delete:me:connected_accounts 作用域:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const { MyAccountClient } = require('@auth0/myaccount-js');

// 用实际值替换占位符
const DOMAIN = 'YOUR_AUTH0_DOMAIN';
const ACCESS_TOKEN = 'USER_ACCESS_TOKEN_WITH_SCOPES'; // 必须具有 delete:me:connected_accounts 作用域
const ACCOUNT_ID_TO_REMOVE = 'auth0|1234567890'; // 要解除关联的账户ID

async function unlinkConnectedAccount() {
  // 1. 初始化MyAccount客户端
  const myAccountClient = new MyAccountClient({
    domain: DOMAIN,
    token: ACCESS_TOKEN
  });

  try {
    console.log(`正在尝试解除关联账户ID: ${ACCOUNT_ID_TO_REMOVE}`);

    // 2. 使用SDK方法删除账户
    await myAccountClient.connectedAccounts.delete(ACCOUNT_ID_TO_REMOVE);

    console.log(`成功解除关联账户ID: ${ACCOUNT_ID_TO_REMOVE}`);
  } catch (error) {
    console.error('删除关联账户时出错:', error.message);
  }
}

这个 unlinkConnectedAccount() 函数使用Auth0域和用户的访问令牌(必须包含 delete:me:connected_accounts 作用域)初始化 MyAccountClient。然后它调用 myAccountClient.connectedAccounts.delete() 方法,传入要移除的账户ID。最后,如果账户成功解除关联则记录成功消息,如果操作失败则记录错误。

立即简化自助式账户管理

Auth0 My Account API标志着在简化安全的、自助式用户管理功能的开发方面迈出了重要一步。通过提供专用的、用户作用域的端点,它使开发者能够自信地将关键的账户功能(如通行密钥注册和账户关联)从复杂的后端代理中移出,直接放入客户端应用程序中。这带来了更清晰的架构、更快的开发周期和更流畅的用户体验。

请记住,在撰写本文时,该功能处于有限早期访问阶段。请联系您的Auth0客户经理以请求访问权限。

下载 myaccount-js SDK,在您基于JavaScript的应用程序中使用它,并在下方告诉我们您的想法或提出任何问题。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计