当使用 Tiny Cloud 服务时,TinyMCE AI 需要 JWT (JSON Web Token) 身份验证。JWT 身份验证为 TinyMCE AI 功能提供安全的、用户特定的访问权限。每个 JWT 令牌都包含声明,用于识别用户并指定其可访问的 AI 功能。
本页面介绍了针对Tiny Cloud 托管版 AI 服务的 JWT 身份验证,其中
aud声明设置为 Tiny Cloud API 密钥,且令牌使用 RS256 签名。对于本地部署环境,aud声明是管理面板中的环境 ID,且令牌使用 HS256 签名。有关本地部署 AI 服务的 JWT 身份验证信息,请参阅 本地部署 AI 服务的 JWT 身份验证。
TinyMCE 建议使用 jwt.io/libraries 上列出的库来创建 JWT 令牌。这些库支持 TinyMCE AI 所需的算法。有关支持的算法的详细信息,请参阅支持的算法。
试用:演示身份服务
在 Tiny Cloud 试用期间,TinyMCE AI 插件可使用演示身份服务。在试用期间,无需设置自定义令牌端点即可尝试该插件。演示服务会为最终用户分配一个随机会话和用户 ID,然后为该用户生成 JWT。这可以防止用户查看彼此的对话历史。
快速开始
以下是使用演示身份服务的最简单方法。将 {apiKey} 替换为从 客户门户获取的试用 API 密钥。
在生产环境中,用户会话的作用域应限定为页面级别,而非特定的 TinyMCE 实例。为方便起见,本示例将其放在
tinymceai_token_provider选项中。如果页面上有多个 TinyMCE 实例,这可能会导致用户方面出现意外行为。在这种情况下,应确保每个页面仅运行一次会话获取操作。
tinymce.init({
selector: "textarea",
plugins: "tinymceai",
toolbar: "tinymceai-chat tinymceai-review tinymceai-quickactions",
sidebar_show: 'tinymceai-chat',
tinymceai_token_provider: async () => {
await fetch(`https://demo.api.tiny.cloud/1/no-api-key/auth/random`, { method: "POST", credentials: "include" });
return await fetch(`https://demo.api.tiny.cloud/1/no-api-key/jwt/tinymceai`, { credentials: "include" })
.then(resp => resp.text())
.then(token => ({ token }))
}
});实际使用示例
在生产环境中,用户和会话管理通常发生在页面级别。本示例展示了演示身份服务两个端点更为实际的使用模式:
// Establish a session with the demo identity service (cookies sent on same-site requests).
const isLoggedIn = fetch(`https://demo.api.tiny.cloud/1/no-api-key/auth/random`, { method: "POST", credentials: "include" });
tinymce.init({
selector: "textarea",
plugins: "tinymceai",
toolbar: "tinymceai-chat tinymceai-review tinymceai-quickactions",
sidebar_show: 'tinymceai-chat',
tinymceai_token_provider: async () => {
// Wait for the session request so the JWT endpoint receives the session cookie.
await isLoggedIn;
// Return a JWT string in the shape the AI plugin expects: { token }.
return await fetch(`https://demo.api.tiny.cloud/1/no-api-key/jwt/tinymceai`, { credentials: "include" })
.then(resp => resp.text())
.then(token => ({ token }))
}
});过渡到生产环境
要从演示身份服务过渡到生产系统,请执行以下操作:
将演示服务中的会话调用替换为您自己的用户管理方式。如果没有用户的概念,则为每个会话或页面生成一个随机标识符,以确保最终用户不会共享对话历史。
按照本指南所述设置一个可创建 JWT 的 JWT 端点。将演示服务中的 JWT 获取操作替换为对该端点的调用。有关实现指南,请参阅 Node.js 或 PHP。
令牌端点概述
要将 TinyMCE 与 TinyMCE AI 连接,必须在应用程序后端创建一个令牌端点。本指南概述了创建该端点所需遵循的原则。
TinyMCE AI 如何使用令牌
为验证用户身份,TinyMCE AI 使用令牌。令牌的作用是告知 AI 服务该用户有权访问 AI 功能,并指定该用户应连接的 API 密钥。令牌的真实性通过数字签名来保证。
令牌端点是 TinyMCE 发出请求以获取令牌的位置。只有在用户证明其身份后,该端点才能返回令牌。它应放置在系统内部,不应在未经过适当身份验证的情况下作为公共端点暴露。
下图展示了 TinyMCE AI 如何使用令牌:
JSON Web Tokens 规范
TinyMCE AI 令牌以 JSON Web Tokens (JWT) 的形式表示。JWT 是一种用于传输数字签名信息的开放标准 (RFC 7519)。使用它可确保数据来自可信来源且未被篡改。
JWT 由三部分组成,各部分之间以点 . 分隔:
头部 (Header):包含有关令牌的元数据,包括签名算法
有效载荷 (Payload):包含声明(用户信息、权限等)
签名 (Signature):用于验证令牌的真实性
{header}.{payload}.{signature}示例:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQ4NzI5IiwibmFtZSI6Ikplc3NpY2EgV2lsbGlhbXMiLCJpYXQiOjE3Mjg0NzM2NDJ9.kX9mP2qL8vN4rT7wY3zA5bC6dE1fG2hI3jK4lM5nO6pQ7rS8tU9vW0xY1zA2b
头部
JWT 的头部标识令牌类型,并指定用于签署令牌的加密算法。对于 TinyMCE AI,头部必须是一个包含以下内容的 JSON 对象:
alg:用于创建令牌签名的签名算法。有关支持的算法列表,请参阅支持的算法。Tiny 建议使用RS256。typ:令牌类型标识符,必须始终为JWT
头部经过 Base64URL 编码后形成 JWT 令牌的第一部分。
头部示例{
"alg": "RS256",
"typ": "JWT"
}负载
JWT 的负载是一个 JSON 对象,其中包含用于标识用户、指定其 AI 权限以及控制令牌有效期的声明。负载经过 Base64URL 编码后形成 JWT 令牌的第二部分。
负载属性
负载中必须包含以下属性:
aud:有权使用 TinyMCE AI 的 API 密钥。sub:用户 ID。这应该是发起请求的用户的唯一标识符。此标识符用于将对话历史、AI 生成的内容以及其他特定于用户的数据锁定到各个用户,以确保隐私和数据隔离。用户 ID 不得超过 96 个字符。iat:“签发时间”。确保存在iat并且包含以秒为单位的正确时间。某些 JWT 实现默认不包含它。有时系统时间也可能无效,从而导致问题。exp:令牌过期时间。标识 JWT 在此时间之后将不被接受。TinyMCE AI 仅接受不超过 24 小时的令牌。可以使用此字段缩短令牌的有效期。auth:内部必须包含auth.ai.permissions数组。这定义了用户可以访问哪些 AI 功能。有关详细信息,请参阅下方的权限。
在一次编辑器会话期间返回的每个令牌都必须携带与第一个令牌相同的 sub 和 aud 值。要切换到不同的用户或 API 密钥,请重新加载编辑器。请参阅 sub 或 aud 声明已更改。
每个令牌还必须满足以下要求,否则编辑器将显示错误并且不会发送请求:
它包含
sub、aud、iat、exp以及auth.ai.permissions数组。否则,错误为Invalid JWT token payload。它不超过其
exp时间两分钟。其
iat和exp时间不超过过去 24 小时。
未通过任一时间检查的令牌将产生错误 JWT token has expired。
可选的属性:
user:用户信息。为了获得更好的用户体验和调试,建议提供name和email。
令牌负载示例
以下示例展示了一个完整的令牌负载:
{
"aud": "no-api-key",
"iat": 1511963669,
"exp": 1511967269,
"sub": "user-123",
"user": {
"email": "user@example.com",
"name": "John Doe"
},
"auth": {
"ai": {
"permissions": [
"ai:conversations:read",
"ai:conversations:write",
"ai:models:agent",
"ai:actions:system:*",
"ai:reviews:system:*"
]
}
}
}权限
权限在 JWT 令牌内的 auth.ai.permissions 数组中指定,并控制用户可以访问哪些 AI 功能、模型和能力。
有关可用权限的完整列表、权限示例和最佳实践,请参阅权限。
有关所有必需声明(包括类型、格式和实现示例)的完整详细信息,请参阅:
签名
签名是通过使用 Base64URL 对头部和负载进行编码,然后使用指定的算法通过私钥对其进行签名来创建的。TinyMCE AI 服务使用存储在 Tiny 账户中的相应公钥来验证签名。
支持的算法
TinyMCE 不支持对称加密算法,例如 HS256。Tiny 建议使用 RS256 算法。以下算法受支持:
RS256
RS384
RS512
PS256
PS384
PS512
有关这些算法的详细信息,请访问:RFC 7518,JSON Web 算法 (JWA) 第 3 节 - 用于数字签名和消息认证码的加密算法。
对令牌端点的请求
TinyMCE AI 令牌由 TinyMCE AI 插件请求。最简单的配置方法是将 tinymceai_token_provider 选项设置为从端点获取令牌的函数。
将请求令牌端点:
在编辑器初始化时
当当前令牌距离其
exp过期时间不足60秒时,在下一次请求AI服务时
简单用法
tinymce.init({
selector: 'textarea',
plugins: 'tinymceai',
toolbar: 'tinymceai-chat tinymceai-quickactions tinymceai-review',
tinymceai_token_provider: () => {
return fetch('http://localhost:3000/jwt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
}).then(response => response.json());
},
});在编辑器加载时会请求第一个令牌。如果令牌请求失败,编辑器仍会启动,但会出现错误通知,并且在令牌端点返回有效令牌之前,TinyMCE AI请求都会失败。
令牌端点的响应
令牌提供程序必须返回一个Promise,该Promise解析为一个包含token属性的对象:{ token: string }。如果该函数未返回Promise,或者解析后的值没有token字符串,插件将报告错误。端点可以采用以下任一格式响应:
JSON响应:端点返回
{ "token": "eyJ..." }。使用response.json()并返回{ token: data.token }。纯文本响应:端点返回原始JWT字符串。使用
response.text()并返回{ token }。
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}示例:纯文本响应eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
快速设置
要为TinyMCE AI设置JWT认证:
生成公钥/私钥对,并使用Tiny Account - JWT Keys将公钥添加到Tiny账户中。
设置一个JWT端点,该端点生成包含所需声明的令牌。
通过
tinymceai_token_provider选项配置TinyMCE以使用JWT端点。
有关包含完整代码示例的分步实现说明,请参阅:
JWT认证(Node.js):完整的Node.js实现指南
JWT认证(PHP):完整的PHP实现指南
工具
可以使用jwt.io调试器来验证和调试JWT令牌。
故障排除
无效令牌
如果错误消息表明令牌无效:
验证令牌是否根据所需声明和格式创建
确保
aud声明中的API密钥正确且有效验证令牌是否使用支持的算法之一签名
检查Tiny账户中的公钥是否与用于签名令牌的私钥匹配
使用jwt.io调试器验证令牌结构
检查令牌是否具有所有必需的声明且未过期,如“负载属性”中所述
确保
iat(签发时间)时间戳正确且不在未来验证系统时间是否准确(时间偏差可能导致令牌验证问题)
如果错误代码为
jwt-too-long,则减少声明的大小
权限不足
如果错误表明权限不足:
验证令牌是否包含具有所需权限的
auth.ai.permissions数组检查权限是否与正在访问的AI功能匹配
查阅权限指南以获取正确的权限格式
确保权限已正确指定(例如,
ai:conversations:read,ai:conversations:write)添加
403missing-permissions响应中data.missingPermissions数组列出的范围
sub或aud声明已更改
如果插件报告JWT令牌声明(sub或aud)自上次令牌签发以来已更改,则令牌提供程序在同一编辑器会话期间为不同的用户或API密钥返回了令牌。在整个会话中返回具有相同sub和aud的令牌,或者在用户更改后重新加载编辑器。
错误代码
有关错误响应形状,请参阅错误响应。有关完整错误代码列表,请参阅API参考。令牌相关的修复在“无效令牌”和“权限不足”中。
相关功能
快速操作:内容转换。
API 文档:TinyMCE AI 的完整 API 参考。