@ 声明/嵌入
嵌入式主机集成 SDK 声明 屏幕 作为第三方应用程序中的白标签 iframes.
装入时未装入声明外壳的屏幕路径
与 ?embed=1. 主机应用程序拥有外壳、导航和身份;
声明拥有屏幕渲染,数据访问,以及租户隔离. 这个
软件包是两边的输入式集成层 :
- 浏览器核心 (单位:千美元)
@declarion/embed——无依赖性. 创建 iframe,运行认证握手,自动调整大小,镜像导航. - 反应绑定 (单位:千美元)
@declarion/embed/react) - (英语)<DeclarionEmbed />。 。 。 . - 服务器助手 (单位:千美元)
@declarion/embed/server) - (英语)createEmbedSession,则 节点边薄荷呼叫。 留着dcl_API 密钥出自浏览器代码.
只安装主机 @declarion/embed它确实如此 没有 取决于
@declarion/react (全声明UI SDK).
安装
npm install @declarion/embed
react 财务报告和审定财务报表 react-dom 是可选的同伴依赖关系,仅由
@declarion/embed/react 输入.
嵌入如何工作
- 宿主的后端薄荷为目标租户和
用户为
createEmbedSession(单位:千美元)@declarion/embed/server),它称为auth.create_embed_session使用服务器控件的动作dcl_API密钥. - 主机前端嵌入了屏幕
createDeclarionEmbed或者说<DeclarionEmbed />,通过一个getToken获取符号的回调 从主机后端. - SDK运行一个
postMessage握手: iframe要求一个符号 SDK提供它, 当iframe报告到期时更新它.
这个 dcl_ API 密钥从不离开主机后端. 对于多租户主机,请使用
最低特权 dcl_ 密钥,其服务账户所有者只持有该密钥
action:auth.create_embed_session; 租户范围钥匙只能用薄荷
自己的租户.
Token 模型和持久性框架
嵌入式代币是每件 (用户、租户) 并装满用户
有效权限。 用户可以打开的屏幕都有一个符号 - 是
不是每个屏幕。 每一次将它薄荷并再用; getToken 应该是
绑入身份,而不是当前屏幕.
切换屏幕速度快,因为 Iframe 是 持久性: 改变
route (单位:千美元) route 道具,或 handle.navigate(route)(表1)
SPA-导航现有iframe. 该应用程序保持其加载的策略和
会话 - 它不重新装入或重新勾选每个屏幕的图案 。 第一个负载
获取一次 schema; 之后的屏幕开关是前端- 速度 .
更改嵌入式 身份 (不同用户或租户)必须重建
iframe,因为 iframe 缓存是权威形状的。 与
反应绑定,通过一个马厩 identityKey (例如:. `${tenant}|${user}`(三);
更改它重建了 iframe 和 重置 。 用核心来创建一个新的嵌入
为新身份。 每个屏幕访问在 Iframe 内执行 :
导航时间,永远不要缩小标志.
快速启动: 浏览器核心
import { createDeclarionEmbed } from "@declarion/embed";
const embed = createDeclarionEmbed({
container: document.getElementById("declarion")!,
declarionOrigin: "https://app.example.com",
route: "/cases",
getToken: async () => {
const res = await fetch("/host-api/embed-token");
return res.json(); // { token, expires_at }
},
onError: (err) => console.error(err.code, err.message),
});
// Later: embed.navigate("/cases/42"); embed.setTheme("dark"); embed.destroy();
快速启动: 重现
import { DeclarionEmbed } from "@declarion/embed/react";
export function CasesPanel({ tenant, user, route }) {
return (
<DeclarionEmbed
declarionOrigin="https://app.example.com"
route={route}
// Stable per identity. Changing `route` soft-navigates the SAME iframe;
// changing `identityKey` rebuilds it (a different user must not reuse the
// prior user's authority-shaped schema).
identityKey={`${tenant}|${user}`}
getToken={async () => (await fetch("/host-api/embed-token")).json()}
onError={(err) => console.error(err.code, err.message)}
/>
);
}
快速启动: 服务器助手( 节点)
import { createEmbedSession } from "@declarion/embed/server";
// In a host backend route. The dcl_ API key is read from server config.
const session = await createEmbedSession({
declarionOrigin: "https://app.example.com",
// Prefer a least-privilege dcl_ key whose owner holds only
// action:auth.create_embed_session. Keep it server-side only.
apiKey: process.env.DECLARION_EMBED_API_KEY!,
tenantCode: "acme", // target tenant
userEmail: "[email protected]",
screenCode: "cases_list",
});
// Return `session` ({ token, expires_at }) to the host frontend's getToken.
非节点后端的主机呼叫
POST /api/actions/auth.create_embed_session 通过 HTTP 直接操作
同样的 dcl_ API 键在 Authorization 头曰.
脚本标记( 无构建步骤)
包裹还装有一包IIFE核. 装入并使用
window.DeclarionEmbed.createDeclarionEmbed数字 :
<script src="https://unpkg.com/@declarion/embed/dist/declarion-embed.iife.js"></script>
<script>
DeclarionEmbed.createDeclarionEmbed({ /* options */ });
</script>
导航模式
navigation: "self"(默认) - iframe 路由 Everyy in-frame 链接 内部( 符号是身份扫描的, 所以 iframe 已经授权) 打开用户可以去的任何地方),并发出onNavigate({ mode: "self", route, screenCode, ... })这样主机就可以镜像 (原始内容存档于2017-09-21). Its URL.navigation: "delegated"- iframe从不动于内联 发射onNavigate({ mode: "delegated", route, screenCode, ... })编辑 主机决定打开什么(通过route道具/ 电源handle.navigate) (中文(简体) ). 用此来将嵌入到单个屏幕上.
这个 onNavigate 事件携带 { mode, route, screenCode?, entity?, recordId? }。 。 。 .
由主机驱动 navigate (单位:千美元) route 改变道具,或 handle.navigate是一个
深链接命令:它以两个模式移动iframe(它是主机请求),
作为软的SPA导航——只有机体内LINKS被拦截/授权. 这个
同一符牌授权每个屏幕,所以不需要再加薄荷来切换.
导航失败
当内框导航无法处理时 -- -- 未知路线,或404 -- --
iframe 继续放放放 onNavigationFailed({ route, reason })
(单位:千美元)reason 实值 not_found 或者说 unresolved) (中文(简体) ). 主机拥有恢复:显示自己的恢复
未找到, 或重设其侧边栏选择 。 永远不要打破框架.
createDeclarionEmbed({
// ...
onNavigationFailed({ route, reason }) {
hostRouter.showNotFound(route, reason);
},
});
Iframe 沙盒
SDK设定 sandbox 默认运行完整应用程序的 iframe
省去顶端导航符号,所以被设定的应用程序无法导航主机
顶上窗口。 把它加宽 extraSandbox 选项
顶级导航标志被剥去,永远不能被再加. 留着吧
社区支助方案 frame-ancestors 配置为控件 谁 可能会设定应用程序.
未保存的更改
一个声明屏幕可以持有未保存的编辑. 当主机导航到 Iframe
远离这样的屏幕 - 通过自己的菜单,或 handle.navigate() - 应该
先与用户确认。 iframe通过
onEvent 回调 :
let embedDirty = false;
createDeclarionEmbed({
// ...
onEvent(event) {
if (event.type === "dirty-changed") embedDirty = event.payload.dirty;
},
});
// Before the host moves the iframe away:
if (embedDirty && !confirm("Discard unsaved changes?")) return;
导航 内部 iframe(一行点击,一后键)和主机驱动
route 变化/ handle.navigate 都已经由声明保护:
iframe 在丢弃编辑前显示自己的确认对话框 。 这个 dirty-changed
事件是用于主机动作的 iframe CANNOT 截取 - 主机离开
通过自己的页面导航嵌入,或替换嵌入在身份上
开关。 用它来守护那些.
嵌入时保持当前
当在屏幕嵌入时调出声明部署时
iframe 不显示 Declarion 自己重新装入铬( 在 a 内错误)
白标签主机). 而是要求主机通过一个 reload-required
事件(通过 onError 有代码 embed.reload_required 和通过
onEvent) (中文(简体) ). 主机决定:重新装入iframe,显示自己的横幅,或者忽略.
长长的 Iframe 否则会保持其装入的屏幕开关
并且只在真实版本更改或SSE会话刷新时重新验证.
诊断
错误的配置被浮出水面 onError (类型)
EmbedError 拥有稳定 code(中文(简体) ) 财务报告和审定财务报表 console.error。无信任
跨原产地 postMessage 框被无声地放下。 SDK探测器:
embed.invalid_options- 缺少必要的选项或格式不当.embed.get_token_failed- 说吧getToken拒绝或返回错误结果.embed.handshake_timeout- 在装入后窗口内不握手,通常是declarionOrigincSP 声明否认的不匹配或设定 (单位:千美元)DECLARION_FRAME_ANCESTORS不列出主机来源).embed.reload_requirediframe要求主机重新装入.
此 SDK 和声明部署之间的协议版本不匹配
生成一个清晰的 console.warn 命名两个版本.
拼凑起来
真正的融合是两分之一 上面的片段是整个 合同:
- 主机前端 - 让
<DeclarionEmbed />(反应)或呼叫createDeclarionEmbed(任何框架)和供应合成getToken调用。 SDK拥有iframe,theready- > (中文)set-token握个手, 调整大小, 导航, 和符号刷新 . - 主机后端 - 拿着
dcl_API 密钥( 仅服务器侧) 和薄荷 短寿命、有范围地嵌入的标志createEmbedSession从@declarion/embed/server。您的getToken回话从您那里取一个 拥有后端端.
这个 dcl_ 密钥绝不离开您的服务器; 浏览器只持有一个
短命的,有范围地嵌入符. 分拆是整个安全模式
保留 @declarion/embed/server 退出任何浏览器捆绑.
许可证
麻省理工学院