跳到主要内容

机器对机器:使用 Logto 认证 (Authentication)

备注:

本指南假设你已经在管理控制台中创建了一个类型为“Machine-to-machine”的应用程序。

简介

机器对机器 (M2M) 是一种常见做法,用于在你有一个需要直接与资源通信的应用(不是用户)时进行认证 (Authentication)(通常,使用 M2M 应用不需要用户交互,因此没有 UI)。例如,一个在 Logto 中更新用户自定义数据的 API 服务、一个拉取每日订单的统计服务等。

由于 Logto 使用基于角色的访问控制 (RBAC) 作为访问控制策略,为 M2M 应用分配 M2M 角色是保护你的 API(需要直接服务通信)的必要措施。

信息:

要了解我们当前的 RBAC 以及用户角色和 M2M 角色的区别,请参阅 配置全局角色 了解更多信息。

在 Logto 中使用机器对机器应用有两种常见场景:

  1. 访问 Logto Management API:在这种情况下,你需要为 M2M 应用分配包含内置 Logto Management API 的 all 权限的 M2M 角色。
  2. 访问你的 API 资源:在这种情况下,你需要为 M2M 应用分配包含你 API 资源权限的 M2M 角色。

在创建 M2M 应用程序的过程中,你会被引导到一个页面,在这里你可以为你的应用程序分配 M2M 角色

分配 M2M 角色弹窗

或者,当你已经创建了 M2M 应用程序后,也可以在 M2M 应用详情页分配这些角色:

分配 M2M 角色页面

现在,让我们一起走完整流程。为清晰起见,我们将访问 Logto Management API 和其他 API 资源的步骤分开。并假设你已经在 Logto 中创建了一个 M2M 应用。

获取访问令牌 (Access token)

关于访问令牌 (Access token) 请求的基础知识

M2M 应用通过向令牌请求端点发送 POST 请求来获取访问令牌 (Access token),在 HTTP 请求实体主体中使用 application/x-www-form-urlencoded 格式添加以下参数:

  • grant_type:必须设置为 client_credentials
  • resource:你想要访问的资源
  • scope:访问请求的权限 (Scope)

你还需要在请求头中包含 M2M 应用的凭据,以便令牌请求端点认证 (Authentication) 你的 M2M 应用。

这是通过在请求的 Authorization 头中以 基本认证 (Basic authentication) 形式包含应用的凭据来实现的,其中用户名是 App ID,密码是 App Secret。

你可以在 M2M 应用的详细信息页面找到 App ID 和 App Secret:

App ID and App Secret

一个访问令牌 (Access token) 请求示例如下:

POST /oidc/token HTTP/1.1
Host: your.logto.endpoint
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&resource=https://shopping.api
&scope=read:products write:products

请求访问令牌 (Access token)

备注:

在以下演示中,将 https://your.logto.endpoint 替换为你要访问的 Logto endpoint。对于 Logto Cloud,它将是 https://{your-tenant-id}.logto.app

Logto 提供了内置的 “Logto Management API” 资源,这是一个只读资源,拥有 all 权限用于访问 Logto Management API,你可以在 API 资源列表中看到它。 该资源的 API 指示器模式为 https://{your-tenant-id}.logto.app/api,这将是你在访问令牌 (Access token) 请求体中使用的资源值。

Logto Management API details

在访问 Logto Management API 之前,请确保你的 M2M 应用已被分配包含该内置 “Logto Management API” 资源 all 权限的 M2M 角色 (Role)。

信息:

Logto 还为新创建的租户预配置了 “Logto Management API access” M2M 角色 (Role),该角色已分配了 Logto Management API 资源的 all 权限。你可以直接使用,无需手动设置权限。此预配置角色也可以根据需要进行编辑和删除。

现在,将以上内容组合起来并发送请求:

信息:

自 v1.30.1 版本起,Logto 提供了官方的 @logto/api Node.js SDK,帮助你轻松与 Logto Management API 交互。

Logto Cloud

import { createManagementApi } from '@logto/api/management';

const { apiClient, clientCredentials } = createManagementApi('your-tenant-id', {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});

const { value } = await clientCredentials.getAccessToken();
console.log('Access token:', value);

// 或者你甚至可以跳过获取访问令牌 (Access token),直接调用 API
const response = await apiClient.GET('/api/users');
console.log(response.data);

自托管 / OSS

OSS 用户应使用 default 作为租户 ID,并同时提供 baseUrlapiIndicator 配置。

const { apiClient, clientCredentials } = createManagementApi('default', {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
baseUrl: 'https://your.logto.endpoint',
apiIndicator: 'https://default.logto.app/api',
});

访问令牌 (Access token) 响应

一个成功的访问响应体如下:

{
"access_token": "eyJhbG...2g", // 使用此令牌访问 Logto Management API
"expires_in": 3600, // 令牌过期时间(秒)
"token_type": "Bearer", // 使用访问令牌时请求的认证类型
"scope": "all" // Logto Management API 的 scope `all`
}
备注:

Logto 目前不支持 M2M 应用表示用户。访问令牌 (Access token) 负载中的 sub 将是应用 ID。

使用访问令牌 (Access token) 访问资源

你可能会注意到令牌响应中有一个 token_type 字段,它固定为 Bearer

因此,当你与 API 资源 (API resource) 服务器交互时,应该将访问令牌 (access token) 以 Bearer 格式(Bearer YOUR_TOKEN)放在 HTTP 头的 Authorization 字段中。

使用 @logto/api SDK,你可以直接与任何 Management API 交互,参考下面的代码片段。访问令牌 (Access token) 会在内部缓存,并在需要时自动刷新。

import { createManagementApi } from '@logto/api/management';

const { apiClient } = createManagementApi('your-tenant-id', {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});

const response = await apiClient.GET('/api/applications');
console.log(response.data);

授权 (Authorization)

如果你保护的是自己的 API 资源(而不是 Logto Management API),你需要在 API 服务中实现授权 (Authorization) 逻辑,以验证访问令牌 (Access token) 并检查 M2M 应用是否有访问该资源所需的权限。

更多详情请参阅 授权 (Authorization)验证访问令牌 (Access tokens)