创建自定义令牌声明脚本
要向访问令牌 (Access token) 添加自定义声明,你需要提供一个返回包含这些声明的对象的脚本。该脚本应编写为一个返回自定义声明对象的 JavaScript 函数。
-
导航到 控制台 > 自定义 JWT。
-
你可以为两种不同类型的访问令牌自定义访问令牌声明:
- 用户访问令牌:为终端用户颁发的访问令牌。例如,用于 Web 应用程序或移动应用程序。
- 机器对机器访问令牌:为服务或应用程序颁发的访问令牌。例如,用于机器对机器应用程序。
不同类型的访问令牌可能具有不同的令牌负载上下文。你可以分别为每种类型的访问令牌自定义令牌声明。
选择你想要自定义令牌声明的任何类型的访问令牌,然后点击 添加自定义声明 按钮以创建新脚本。
实现 getCustomJwtClaims() 函数
在 自定义 JWT 详情页面,你可以找到编写自定义令牌声明脚本的脚本编辑器。该脚本应为一个返回自定义声明对象的 JavaScript 函数。
步骤 1:编辑脚本
使用左侧的代码编辑器修改脚本。为你提供了一个默认的返回空对象的 getCustomJwtClaims,你可以从此开始。你可以修改该函数以返回你自己的自定义声明对象。
const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
return {};
};
此编辑器使用 JavaScript 语言服务器提供基本的语法高亮、代码补全和错误检查。输入参数已在 jsDoc 风格中进行了良好的类型定义和文档记录。你可以使用编辑器的 IntelliSense 正确访问输入对象的属性。你可以在页面右侧找到详细的参数定义。
此函数将作为模块导出。确保函数名称保持为 getCustomJwtClaims,以便模块可以正确导出该函数。
步骤 2:输入参数
getCustomJwtClaims 函数接受一个对象作为输入参数。输入对象包含以下属性:
token
令牌负载对象。此对象包含你可能需要在脚本中访问的原始令牌声明和元数据。
你可以在页面右侧找到令牌负载对象和用户数据对象的详细类型定义。编辑器的 IntelliSense 还将帮助你正确访问输入对象的这些属性。
- 用户访问令牌数据对象
属性 描述 类型 jti唯一的 JWT id stringaud令牌的受众 stringscope令牌的权限 stringclientId令牌的客户端 id stringaccountId令牌的用户 id stringexpiresWithSession令牌是否会随会话过期 booleangrantId令牌的当前认证 (Authentication) 授权 id stringgty令牌的授权类型 stringkind令牌类型 AccessToken - 机器对机器访问令牌数据对象
属性 描述 类型 jti唯一的 JWT id stringaud令牌的受众 stringscope令牌的权限 stringclientId令牌的客户端 id stringkind令牌类型 ClientCredentials
context(仅适用于用户访问令牌)
上下文对象包含与当前授权 (Authorization) 过程相关的用户数据和授权数据。
- 用户数据对象 对于用户访问令牌,Logto 提供了额外的用户数据上下文供你访问。用户数据对象包含你可能需要设置自定义声明的所有用户资料数据和组织成员数据。请查看 用户 和 组织 (Organizations) 以获取更多详细信息。
- 授权数据对象 对于通过模拟令牌交换授予的用户访问令牌,Logto 提供了额外的授权数据上下文供你访问。授权数据对象包含来自主体令牌的自定义上下文。请查看 用户模拟 以获取更多详细信息。
environmentVariables
使用右侧的 设置环境变量 部分为你的脚本设置环境变量。你可以使用这些变量来存储敏感信息或配置数据,而不想在脚本中硬编码。例如,API 密钥、密钥或 URL。
你在此处设置的所有环境变量都将在脚本中可用。使用输入参数中的 environmentVariables 对象来访问这些变量。
api
api 对象提供了一组实用函数,你可以在脚本中使用这些函数对令牌颁发过程进行额外的访问控制。api 对象包含以下函数:
api.denyAccess(message?: string): void
api.denyAccess() 函数允许你通过自定义消息拒绝令牌颁发过程。你可以使用此函数在令牌颁发过程中执行额外的访问验证。
步骤 3:获取外部数据
你可以使用节点内置的 fetch 函数在脚本中获取外部数据。fetch 函数是一个基于 Promise 的函数,允许你向外部 API 发起 HTTP 请求。
const getCustomJwtClaims = async ({ environmentVariables }) => {
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${environmentVariables.API_KEY}`,
},
});
const data = await response.json();
return {
data,
};
};
请注意,任何外部数据获取可能会引入令牌颁发过程的延迟。确保外部 API 足够可靠和快速以满足你的要求。
此外:
- 在脚本中正确处理错误和超时,以避免令牌颁发过程被阻塞。
- 使用适当的授权头保护你的外部 API 免受未经授权的访问。
步骤 4:测试脚本
确保在保存脚本之前对其进行测试。点击页面右侧的 测试上下文 标签以修改用于测试的模拟令牌负载和用户数据上下文。
点击编辑器右上角的 运行测试 以使用模拟数据运行脚本。脚本的输出将显示在 测试结果 抽屉中。
测试结果是 getCustomJwtClaims 函数在你设置的模拟数据下的输出(在序列图中完成步骤 3 后获得的“额外令牌声明”)。当脚本在令牌颁发过程中执行时,真实的令牌负载和用户数据上下文将有所不同。
点击 创建 按钮保存脚本。自定义令牌声明脚本将被保存并应用于访问令牌颁发过程。