替换连接 SDK
一个轻量级的JavaScript SDK,用于将 OAuth 集成嵌入,以及终端用户自有的API密钥用于管理机密提供者,输入一个应用程序. SDK在桌面弹出中打开了Alter Connection,在移动分类设备上使用全页导航,或者在应用程序提供的元素内使内入,并在引用打入回调前验证完成数据.
已打入 OAuth 调用 QQ 佐德验证有效载荷 QQ 类型Script 包含
快速启动
1. 安装
npm install @alter-ai/connect
软件包元数据宣布了npm工具的Node.js 20.19或以后. 浏览器 执行不需要节点.js。 或者通过CDN使用UMD捆:
<script src="https://cdn.jsdelivr.net/npm/@alter-ai/connect@latest/dist/alter-connect.umd.js"></script>
2. 从应用程序后端获取会话键
应用程序后端使用 更改 SDK数字 :
// Application backend (Node.js example using @alter-ai/alter-sdk)
import { App, CallerType } from "@alter-ai/alter-sdk";
const alterApp = new App({
apiKey: process.env.ALTER_API_KEY!,
caller: "my-backend",
callerType: CallerType.SERVICE,
});
const session = await alterApp.createConnectSession({
allowedProviders: ["provider-id"],
allowedOrigin: "https://app.example.com",
// Optional. When the user approves access, the Connect UI also lets them set
// their own usage limits on the connection being created — deny rules,
// human approval, time windows, request quotas, and operation/parameter
// rules. They can only narrow what they are granting, never widen it, and
// they can change or remove the limits later in their wallet.
//
// This step is enabled by default. To hide it, pass:
// allowUserPolicyRules: false,
});
const sessionToken = session.sessionToken;
3. 打开连接用户界面
import AlterConnect from '@alter-ai/connect';
// Initialize SDK (no API key needed!)
const alterConnect = AlterConnect.create();
const connectButton = document.querySelector('#connect-button');
if (!(connectButton instanceof HTMLButtonElement)) {
throw new Error('Connect button is missing');
}
connectButton.disabled = true;
// Prefetch before the user interacts. Browsers may block a popup opened only
// after an awaited network request has detached it from the click gesture.
let sessionToken = null;
fetch('/api/alter/session')
.then(response => response.json())
.then(({ session_token }) => {
sessionToken = session_token;
connectButton.disabled = false;
})
.catch(() => {
console.error('Unable to prepare the Connect session');
});
connectButton.addEventListener('click', () => {
if (!sessionToken) return;
void alterConnect.open({
token: sessionToken,
onSuccess: (grants, completion) => {
console.log('Connected!', grants);
grants.forEach(grant => console.log(grant.provider, grant.grant_id));
completion.failedGrants.forEach(failure => {
console.warn(failure.providerId, failure.reason, failure.message);
});
},
onError: (error) => {
console.error('Failed:', error);
},
onExit: () => {
console.log('User closed the window');
}
});
});
包会发射主机"OAuth Connect UI",并在召回前验证桌面弹出结果.
框架实例
React, Vue, Angular, Svelte, 和香草应用使用相同的模式:
- 创建一个可重用
AlterConnect举个例子. - 在启用连接按钮前获取会话符号 .
- 打电话
open()直接在点击处理器中,所以弹出活性仍然附于用户手势上. - 当自有组件卸载时销毁实例 .
CDN捆绑暴露的阶级与 window.AlterConnect. 共同司法体系
消费者读取默认导出方式
require('@alter-ai/connect').default。 。 。 .
API 参考
AlterConnect.create(config?)
创建新的 SDK 实例 .
const alterConnect = AlterConnect.create({
debug: true // Enable console logging (default: false)
});
| 选项 | 类型 | 说明 | 默认 |
|---|---|---|---|
debug | boolean | 启用调试日志 | false |
baseURL | string | 保留和不支持。 传递任意值抛出. | —— 说 |
说明: 视觉定制(颜色,字体,标志)通过开发者门户品牌设置进行配置. Alter Connect自动应用所配置的品牌.
alterConnect.open(options)
尝试打开连接 。 桌面使用中心弹出窗口(500×700 px). 移动保密设备使用全页导航,限制记录如下: 移动行为供应 container 使每个设备的元素内部连接( 见 内入模式) (中文(简体) ).
await alterConnect.open({
token: 'sess_abc123...',
onSuccess: (grants, completion) => { /* ... */ },
onError: (error) => { /* ... */ },
onExit: () => { /* ... */ },
onEvent: (eventName, metadata) => { /* ... */ }
});
| 参数 | 类型 | 需求 | 说明 |
|---|---|---|---|
token | string | 对 | 应用后端用 Alter SDK 创建的短寿命会话符号 : sess_… 用于 OAuth 连接或 ms_sess_… (单位:千美元) 管理下机密会议 |
container | HTMLElement | 没有 | 在此附加的元素内连入Render Connection 而不是弹出窗口 。 部件填充元素( 350x300 px 建议最小值) 。 主机页面的出处必须等于会话允许的出处. |
singleProvider | boolean | 没有 | 只内置 OAuth 模式( 为管理下的秘密会话而命名 ) : single_provider 标记(当会话准确指定一个提供者时)。 由用户点击调用,提供者窗口立即打开,容器内有平坦状态行;被屏蔽的窗口倒回内置的平板. 这是采摘者的决定,而不是同意的决定——会议是分开的 direct 旗帜规范主机同意屏幕, 部件不消耗它 . |
onSuccess | (grants, completion) => void | 对 | 使用遗留的赠款阵列和一个输入的完成对象调用 . completion.failedGrants 识别部分失败. |
onError | (error) => void | 没有 | 向浏览器SDK发送失败请求,包括终端供应商拒绝(code: "connect_denied") (中文(简体) ). |
onExit | function | 没有 | 当用户关闭桌面弹出或按下 取消内置部件内置时调用; 这不会标记拒绝的后端会话 |
onEvent | (eventName, metadata) => void | 没有 | 打电话 connect_opened 一次流动发射metadata.mode 命名流程 : popup, (中文(简体) ), redirect,或 embed; 弹出报告被屏蔽 popup_blocked 结束 onError 没有 connect_opened),与 provider_declined 当用户在仍然可以继续的会话中拒绝提供者时 provider_error 当提供者本身在这样的会话中失败时 embed_unsupported 当内置部件必须倒回窗口时 embed_continue 当一个内部管理的秘密流在窗口中继续时,主机页面打开 |
承诺在发射尝试后解决,而不是在用户授权后解决. 失踪或无效 token 或者说 onSuccess 值,包括一个以两个开头的符号 sess_ 也没有 ms_sess_,拒绝以 code: "invalid_options"页:1 container 这不是文件所拒绝的内容 code: "invalid_container",并且主机页面没有 http(s) 来源,或本身在 iframe 中的源,以 code: "embed_unsupported_origin"。 。 。 . baseURL 不是一个 OpenOptions 字段:TypeScript拒绝它,而平版JavaScript则忽略它.
内嵌( 内嵌) 模式
await alterConnect.open({
token: 'sess_abc123...',
container: document.getElementById('alter-connect'),
onSuccess: (grants, completion) => { /* ... */ },
onExit: () => { /* user pressed Cancel inside the widget */ },
});
主机连接 UI 内置 container,应用程序大小。 提供方的签名无法在一个框架内运行, 因此部件在新窗口中打开: 当单个提供方会话时, 从应用程序自己的点击 single_provider 旗帜以 singleProvider (没有平板),否则来自用户点击部件内的平板;窗口完成时部件更新; open() 本身在此模式下不需要在点击处理器内运行。 部件自带 Cancel 控制器 (onExit。移动设备也使用内置部件(从不使用整页重定向)。 当会议 single_provider 旗帜不为 singleProvider,或者浏览器屏蔽了它试图打开的窗口,为确切一个提供者创建的会话显示一个单一的“继续”瓷砖来命名该提供者。 用户在提供者返回后确认连接的方式, 除非此会话也与 direct,它关闭在交货。 拒绝部件在框架内存储的浏览器会自动处理:部件提供"在新窗口中继续",并通过相同的回调完成(onEvent 接收 embed_unsupported) (中文(简体) ).
onSuccess, (中文(简体) ), onError,以及 onExit 通过事件发送器的例外运行
警卫 如果有人扔出, SDK 记录例外, 仍然执行
callback的最终状态/听众清理. onEvent 拆分数 : connect_opened 实值
直接引用,所以它拒绝一个例外 open() 发射后
尝试,而主机流事件 贯穿同一卫士。 终点站
处理器总是被注册并释放流量,所以手动弹出
关闭重置 isOpen() 无论是否 onExit 是否提供
它抛出.
完成数据onSuccess:
为了兼容性,第一个参数仍然是: Grant 对象。 这个
第二项论点明确指出:
interface ConnectCompletion {
grants: Grant[];
failedGrants: Array<{
providerId: string;
reason: string;
message: string;
}>;
}
failedGrants 完全成功是空的。 当至少一个供应商成功时,
它识别了已连接但没有保存的任何提供者: not_selected
(用户没有在"确认"屏幕上选中), activation_failed (这可以
当用户确认时不完成),或者 当选定时另一个代码
使用限制无法适用。 未知 reason 字符串被保留 .
错误对象( 错误) :
{
code: string;
message: string;
details?: Record<string, unknown>;
failedGrants?: Array<{
providerId: string;
reason: string;
message: string;
}>;
}
没有成功赠款或一次或多次失败赠款的完成
onError 而不是仅仅报告成功。 代码是
grant_policy_application_failed 拒绝任何赠款是因为
无法应用选定的使用限制,并且 grant_activation_failed 何时
无法在确认时( 启动
连接再次).
提供者拒绝只有在会话没有剩余可尝试时才为终端.
桌面传送 code: "connect_denied" 改为 onError 编辑 error 事件; a
移动流量 returnUrl 为返回的页面提供相同的代码
error 听着 如果会话仍然提供提供者, 用户尚未提供
拒绝, 已经授权的赠款, 或仍然有一个账户的用户
连接并可以批准, 连接
返回到拾取器上,然后将后端的民意调查留等,以便用户可以
并报告拒绝为非死刑 provider_declined 事件
(单位:千美元)onEvent 编辑 event 而不是一个错误,因为 onError 关闭
连接 UI 并会拖曳一个只拒绝了其中之一的用户
供养者. 供应商的倒闭不是拒绝报告 provider_error
在同一频道,所以应用程序必须在事件名称上分支
而不是把每个通知当作用户的决定。 两者都只是弹出流:移动
returnUrl 流量没有打开窗口可通知 。 关闭弹出
浏览器染色体残留 onExit这不是供货商的否认.
alterConnect.close()
关闭活动弹出( 或删除内置部件) 如果存在, 请停止
当前流程处理器, 删除当前每次打开的调用, 重排
isOpen()输出 close。 。 。 .
alterConnect.close();
alterConnect.destroy()
摧毁 SDK 实例并清理资源.
alterConnect.destroy();
alterConnect.on(event, handler)
注册事件听众 。 返回一个未订阅的函数 .
const unsubscribe = alterConnect.on('success', (grants, completion) => {
console.log('Connected:', grants);
console.log('Providers not kept:', completion.failedGrants);
});
// Later: unsubscribe();
公共汽车活动: success, (中文(简体) ), error, (中文(简体) ), exit, (中文(简体) ), close, (中文(简体) ), event编辑 success 处理器接收 (grants, completion); 数据 event 处理器接收 (eventName, metadata) 并带有非平面过渡 provider_declined, (中文(简体) ), provider_error, (中文(简体) ), embed_unsupported 财务报告和审定财务报表 embed_continue。 。 。 . connect_opened 直接由 open() 并到达每个开口处 onEvent 只有回话.
alterConnect.off(event, handler)
删除先前已注册的事件处理器。 通过相同的处理器引用
提供给 on()。 。 。 .
const handleError = error => console.error(error);
alterConnect.on('error', handleError);
alterConnect.off('error', handleError);
alterConnect.isOpen()
返回 SDK 的开国旗 。 它变成 true 当发射开始和
返回到 false 何时 close() 运行。 手动关闭的弹出重排
无论是否自动 onExit 是否提供,是否提供
呼叫回击.
if (alterConnect.isOpen()) {
console.log('Connect is open');
}
alterConnect.getVersion()
获得SDK版本.
console.log(alterConnect.getVersion()); // the installed package version
返回已发布的软件包版本.
移动行为
没有 container,SDK使用用户代理,触摸,取景口和取向检查来选择流量:
| 设备 | 流动 | 如何运作 |
|---|---|---|
| 桌面 | 弹出 | 打开一个中心弹出( 500x700px),并通过回调报告完成 |
| 移动密闭取景口 480 px | 重定向 | 导航连接的完整页面 |
| 移动分类取景口 481–1024 px 在肖像 | 重定向 | 导航连接的完整页面 |
| 其他设备 | 弹出 | 使用桌面回调流程 |
任何设备, container 提供 | 内入 | 在元素内渲染主机UI; 提供商在新窗口( 手机上的新标签) 中打开签名, 部件通过调用完成报告 |
重新定向完成 : 全页导航会破坏原页所注册的回调和收听者. 设定 returnUrl 在会话上,Connect会随结果返回到它,结果将交给在返回页面构建的实例上注册的回调。 不包含 SDK 薄荷每流值的回调参数被忽略 。 未创建会话 returnUrl,并在流量开始后5分多分钟返回,完成 createConnectSession() 加号 pollConnectSession() 在应用程序后端.
关闭桌面弹出引用 onExit 当地,窗口之后不久
关闭(在关闭前发送的结果),
但不会向后端发送拒绝切换。 服务器端的民意调查将持续到到期
或届会结束.
提供商同样可以自行作出授权错误,而无需
重新定位到阿尔特 浏览器 SDK 无法查看该页面或制造
提供者错误 。 服务器 SDK 投票结果为
ConnectTimeoutError· ; details.reason 区分当地投票期限
从最初观察到的、但后来到期的届会开始.
警卫
- API 密钥留在后端. 前端只收到由应用程序后端刻制的短寿命会话符号.
- 浏览器中没有 API 密钥或提供者证书 . 前端只接收寿命短的 Connect 会话符号.
- 内置部件与主机页面隔离 . 它使Alter的发端在一个框架里,主机页面不能读取,只接受会话允许的发端为它的发端,只将结果交给了发端. 提供商的登录总是在顶层窗口中运行.
提供者选择
托管的UI允许提供商参加会话. 当该提供者尚未连接时,一个提供者的许可列表仍然提供一个提供者。 现有健康连接的经核实的用户可以使用同意快速路径; 2; requestedGrant在场时,控制要求的兄弟姐妹补助金。 设定 switchAccount: true ,同时创建会话以强制完全提供商授权.
会话控制的行为
提供方许可列表、每个提供方请求的范围、来源约束、用户身份、请求的兄弟姐妹赠款、授权代理、授权授权范围限制、账户切换、赠款到期范围以及政策作者是会议创建方面的关切。 他们不是浏览器 OpenOptions. 赠款到期限在主机确认屏幕上添加了取时器.
服务器 SDKs 的恢复会话 createConnectSessionForError() 实值
与任何其他会议一样通过 sessionToken 改为 open()这个
浏览器软件包导出任何服务器侧例外类, 包括
ReAuthRequiredError, (中文(简体) ), NoDelegatedGrantError, (中文(简体) ), GrantNotFoundError, (中文(简体) ),
CredentialRevokedError,或无头流 ConnectFlowError 家属
(单位:千美元)ConnectDeniedError, (中文(简体) ), ConnectConfigError, (中文(简体) ), ConnectTimeoutError) (中文(简体) ).
与 allowUserPolicyRules 启用后, 主机的 UI 可以缩小否认,
人力审批,时间窗口,定额,以及操作/参数内容规则.
人类的认可在后来的API调用时发生; 连接只有作者的规则. 若为
选中的规则无法适用于某些提供者,
completion.failedGrants 报告部分失败。 如果没有赠款,
onError 接收 grant_policy_application_failed。 。 。 .
管理秘密会议
管理下的秘密连接会让终端用户为管理下的秘密提供者输入自己的API密钥,或者批准使用他们已经持有的赠款,以及可选地授权访问代理商. 应用程序后端用 Alter 服务器 SDK 创建并手取其 sessionToken (开始于 ms_sess_改为: open()和OAuth一样 部件打开管理后的秘密页面 ms_sess_ 符号和 OAuth 页面 sess_ 以物配主,并拒绝以物配主 invalid_options。 。 。 .
// Application backend
const session = await alterApp.createManagedSecretConnectSession({
provider: "<provider-slug>", // the provider's slug, not its template id
userToken: "<user-jwt>",
allowedOrigin: "https://app.example.com",
agent: "<agent-id-or-name>", // optional: omit for the application's own use
});
// Browser
await alterConnect.open({
token: session.sessionToken,
onSuccess: (grants, completion) => {
if (completion.kind !== "managed_secret") return;
const { path, credentialKind, preflight } = completion.managedSecret;
// grants[0].grant_id is the grant to use: the agent's delegation when an
// agent was named (also grants[0].delegation?.grant_id), else the user's grant.
console.log(path, credentialKind, preflight?.status, grants[0].grant_id);
},
onExit: () => {
// The user cancelled (popup or inline).
},
onError: (error) => {
// "access_denied": the user cancelled on a redirect return. Any other code:
// the request ended before it was answered (for example "session_expired"
// or "key_attempts_exhausted"); create a new session.
},
});
completion.kind 实值 "managed_secret" 用于 ms_sess_ 符号和 "oauth" (单位:千美元) sess_ 符号; 部件从符号中设置, 从主机页面中选择 . completion.managedSecret 报告用户确认的内容:
| 外地 | 数值 |
|---|---|
path | key_entry (用户输入了自己的密钥;应用程序可以撤销该授权,绝不编辑), repair (用户替换了所在的密钥 : repairGrantId,或用户自己的密钥已过期的用户), fast_path (用户批准了他们已经持有的赠款) |
credentialKind | end_user (用户自己的密钥)或 developer (一个关键管理员集) |
preflight | 提供者检查用户输入的密钥: { status, message } 与 status passed, (中文(简体) ), inconclusive (未经核实而储存); message 说明原因)或 skipped (无法检查提供者). null 当没有输入密钥时. |
grants 持有一项补助金: provider 是供货商的鼻涕和 scopes 为空。 和一个特工, grants[0].delegation.grant_id 是代理的委托人,代理的许可证. failedGrants 总是空的。 管理下的秘密成功而不产生有效结果 invalid_response。 。 。 .
弹出、重定向和内入(container)所有模式都奏效。 在移动分类设备上,页面导航回会话 returnUrl,而返回页面构建的实例也提供了同样的完成。 内入,主机页面打开自己的窗口,用于登录和密钥条目(报告给 onEvent 作为 embed_continue),并将结果通过框接回. singleProvider 在管理下的秘密会话中被忽略.
类型脚本支持
完整类型脚本定义包括:
import AlterConnect, {
type AlterConnectConfig,
type OpenOptions,
type ConnectCompletion,
type ConnectFailedGrant,
type ManagedSecretConnectCompletion,
type ManagedSecretOutcome,
type Provider,
type Grant,
type AlterError
} from '@alter-ai/connect';
const alterConnect = AlterConnect.create({ debug: true });
await alterConnect.open({
token: sessionToken,
onSuccess: (grants: Grant[], completion: ConnectCompletion) => {
for (const grant of grants) {
console.log(grant.grant_id); // Store this in the application database
console.log(grant.provider);
console.log(grant.scopes);
}
for (const failure of completion.failedGrants) {
console.warn(failure.providerId, failure.message);
}
},
onError: (error: AlterError) => {
console.error(error.code, error.message);
}
});
该包有一个运行时的依赖性:Zod 4在消耗回调数据前验证完整的跨窗口结果有效载荷.
浏览器支持
CJS,ESME和UMD捆绑以ES2020为目标,并使用现代浏览器API,包括弹出或全页导航, postMessage,URL解析,以及 sessionStorage。导入软件包是免副作用的,但是 AlterConnect.create() 必须在浏览器中运行,因为它检查构建过程中的重定向状态。 寄存器的产品E2E套件会锻炼Chromium;它没有建立交叉浏览器版本矩阵. 软件包元数据宣布了npm工具的Node.js 20.19或以后;CDN浏览器的使用不需要Node.js.
解决问题
弹出被屏蔽
问题: 浏览器屏蔽 OAuth 弹出
解决方案 : 保证 alterConnect.open() 直接从用户交互中调用(单击事件):
// May be blocked: the network request runs after the click.
button.addEventListener('click', async () => {
const token = await fetchToken();
void alterConnect.open({ token, onSuccess, onError });
});
// Reliable: fetch before enabling the button.
const token = await fetchToken();
button.disabled = false;
button.addEventListener('click', () => {
void alterConnect.open({ token, onSuccess, onError });
});
内置部件显示出错
问题: open({ container }) 挂载部件,使其出错 onError 随火而起 code: "embed_origin_mismatch"
解决方案 : 主机页面的出处必须等于会话允许的出处(allowedOrigin 在会话创建时,或当删除该应用程序的网站 URL时其来源。 传递嵌入部件的页面的确切来源 .
内置部件永不装入
问题: open({ container }) 挂载部件,保持空出 onError 随火而起 code: "embed_load_timeout" 15秒后
解决方案 : 帧未发送消息:浏览器拒绝主机页面,无法加载,或Alter主机无法访问. 确认页面已送达 http(s) 在会话允许的来源, 并且本身不在 iframe 内( 嵌入主机页面拒绝) open() 与 code: "embed_unsupported_origin" 在前面,然后薄荷 新鲜的会话和重试.
提供者窗口没有打开( 内置模式)
问题: 点击内置部件内的提供者不起作用
解决方案 : 部件从该点击打开新窗口中的提供者签名; 如果浏览器挡住它, 部件会显示一个请求允许弹出站点的信息, 而点击可以重试 .
会话已过期
问题: 主机连接页面报告会话已过期或无效
解决方案 : 会话符号的默认寿命为10分钟. 创建新会话并打开其符号 。 在装入或装入主机页面时检测到过期状态, 将在那里打开; 它不是一个可靠的浏览器 onError 调用.
CORS 错误
问题: 尝试从浏览器代码创建会话
解决方案 : 在应用程序后端用 Alter 服务器 SDK 创建会话,然后只将短寿命会话符号还给浏览器.
支助
- 联合国 https://docs.alterauth.com (中文(简体) )
- 问题: GitHub 问题
- 电子邮件 : 支持@ alterauth.com
许可证
麻省理工学院