很明显 HUB SDK
连接您的网络应用到明显 。 HUB有脚本,一些配置和一个服务器处理器. 你会得到 "与明显相签. HUB),主机屏幕(选择一个计划,选择数据,保存结果,选择一个 每个中心都订阅你的应用软件 刷新符号留在您的服务器上; 页面获得 访问符只在它要求保护数据时才使用.
预览 (0.x). API仍然可能在小版本之间有所改变. 专有: 见 自由主义。 。 。 .
快开始
1. 明确注册您的应用程序。 汉字 (在你的应用页面上,没有代码):
| 设置 | 数值 |
|---|---|
| 转到应用程序 | https://app.example.com/clearly-hub/sign-in |
| 签名客户端 (H2M): 回调 URL | https://app.example.com/clearly-hub/callback, (中文(简体) ), https://app.example.com/clearly-hub/answer, (中文(简体) ), https://hub.clearly.app/components |
| 签名客户端: 签名退出 URL | https://app.example.com, (中文(简体) ), https://hub.clearly.app/components |
| M2M 客户端 | 创建它, 保留服务器上的秘密 |
| 计划 | 给每个你自己的计划 id作为它的 外部参考,例如 pro |
2. 挂载服务器处理器 (节点24+):
import express from 'express';
import { clearlyHub } from '@clearly-hub/node';
const hub = clearlyHub({
clientId: process.env.CLEARLY_HUB_CLIENT_ID,
m2mClientId: process.env.CLEARLY_HUB_M2M_CLIENT_ID,
m2mClientSecret: process.env.CLEARLY_HUB_M2M_CLIENT_SECRET,
appId: process.env.CLEARLY_HUB_APP_ID, // your app's id in Clearly.HUB
appUrl: 'https://app.example.com',
secret: process.env.SESSION_SECRET, // 32+ random characters
});
const app = express();
app.use('/clearly-hub', hub.express());
不是快递? hub.handler 使用一个 Request 返回 a Response,对于Next.js的路由处理器,
霍诺 邦或德诺 装入 /clearly-hub/*。 。 。 .
3. 添加脚本和一个按钮:
<!-- @0.1: follows 0.1.x fixes, not a breaking 0.2 -->
<script src="https://cdn.jsdelivr.net/npm/@clearly-hub/[email protected]/dist/clearly-hub.js"></script>
<clearly-hub-button action="sign-in"></clearly-hub-button>
<clearly-hub-button action="SELECT_DATA"></clearly-hub-button>
<script type="module">
const session = await clearlyHub.session(); // { signedIn, user }
window.addEventListener('clearly-hub-answer', (event) =>
console.log(event.detail),
);
</script>
或者说 npm install @clearly-hub/browser 财务报告和审定财务报表 import { clearlyHub } from '@clearly-hub/browser'中添加 import '@clearly-hub/browser/react' 有一次,所以JSX知道 <clearly-hub-button>。 。 。 .
浏览器软件包
clearlyHub.session() | { signedIn: false },或签名用户(sub, (中文(简体) ), email, (中文(简体) ), name, (中文(简体) ), appUserId(中文(简体) ) |
clearlyHub.signIn(), (中文(简体) ), signOut() | 明显地通过。 HUB 回到这页 |
clearlyHub.signIn({ display: 'popup' }) | 以弹出方式签名; 此页面保留 。 决定开会。 也联系一个明显。 HUB 账户给您自己登录的人 |
clearlyHub.open(action, { data, display }) | 打开主机屏幕;用它选中的答案解决。 通过点击调用它: 浏览器只允许弹出到那里 |
clearlyHub.result() | 在重新定向的屏幕之后:它的答案,在页面上它回到 |
clearlyHub.getToken() | 该人受保护和付费数据的钥匙,或 null 签了字后 见 受保护数据 |
clearlyHub.onAnswer(callback) | 每一个回答,一次从弹出,一次从回转后;也可以在回转后开始听(React). 返回停止监听的函数 |
<clearly-hub-button action display data label> | 标记按钮 sign-in, (中文(简体) ), sign-out 每个屏幕 |
clearly-hub-answer 事件 | 每一个答案,从弹出 或经过方向调整 |
clearly-hub-sign-in 事件 | 签入的弹出完成; detail 是会话 |
搭接按钮. 它用你的页面字体。 普通案件属性:
variant="outline", (中文(简体) ), size="small" 或者说 size="large"。 CSS 自定义属性用于您的外观 :
--clearly-hub-color, (中文(简体) ), --clearly-hub-text-color, (中文(简体) ), --clearly-hub-radius, (中文(简体) ), --clearly-hub-padding, (中文(简体) ),
--clearly-hub-font。对于其它任何问题,请将真实的按钮通过 ::part(button)数字 :
clearly-hub-button {
--clearly-hub-color: #0b7471;
--clearly-hub-radius: 999px;
}
clearly-hub-button::part(button) {
text-transform: uppercase;
}
默认在弹出时打开屏幕( S)data-display="redirect" 或者说 "iframe" 在脚本标签上
修改。 被堵住的弹出会回到方向.
在您页面上的对话框中 (单位:千美元)display: 'iframe': 屏幕显示在中央对话框中并使用
在你的应用软件上签名的人, 所以它不签名本身, Google Drive 拾取器的方式
工作时 弹出也一样 很明显没人和他签约 你的应用程序的签到
首先(一个弹出,在同一个窗口)。 需要一个明显的。 汉字
释放允许此选项( 预览) 。 如果你的应用程序有自己的CSP: frame-src https://hub.clearly.app。 。 。 .
以 --clearly-hub-frame-width, (中文(简体) ), --clearly-hub-frame-height, (中文(简体) ),
--clearly-hub-backdrop,或 clearly-hub-frame::part(dialog | iframe | close)。 。 。 .
| 行动 | 报到 data | answer 何时 result 实值 SUCCESS |
|---|---|---|
SELECT_SUBSCRIPTION | subscription (单位:千美元)_id, (中文(简体) ), externalReference 你的计划id, subscribedHub (单位:千美元)_id, (中文(简体) ), name, (中文(简体) ), hasMultipleSubscriptions | |
SELECT_DATA | 可选择 { formats: ['geojson', 'wms'] } 只提供这些 | activeHub (单位:千美元)_id, (中文(简体) ), name, (中文(简体) ), resources (单位:千美元)datasetId, (中文(简体) ), datasetTitle, (中文(简体) ), resourceId, (中文(简体) ), resourceName, (中文(简体) ), url, (中文(简体) ), format, (中文(简体) ), accessibility, (中文(简体) ), requiresToken, (中文(简体) ), hasAccess(中文(简体) ) |
REGISTER_RESOURCE | { url, format } 在公开的 https URL 中 | activeHub (呼号), dataset (单位:千美元)datasetId, (中文(简体) ), datasetTitle, (中文(简体) ), resource (单位:千美元)resourceId, (中文(简体) ), resourceName(中文(简体) ) |
SELECT_HUB | hub (单位:千美元)_id, (中文(简体) ), name(中文(简体) ) | |
SELECT_DIGITAL_TWIN | activeHub (单位:千美元)_id, (中文(简体) ), name, (中文(简体) ), digitalTwin (单位:千美元)_id, (中文(简体) ), title, (中文(简体) ), description, (中文(简体) ), previewImage, (中文(简体) ), ownerHub, (中文(简体) ), findability, (中文(简体) ), viewerUrl, (中文(简体) ), resources 与 SELECT_DATA 加号 selected 财务报告和审定财务报表 subLayers (单位:千美元)name, (中文(简体) ), selected页:1 |
每一个答案都有 user (单位:千美元)_id, (中文(简体) ), email他回答说:这是明显的。 嘘。 内容 _id 这是
个人的 sub,与 session().user.sub。 。 。 .
受保护数据
受保护或付费的资源 SELECT_DATA (单位:千美元)requiresToken: true拥有一个 url 显然。 汉伯,
检查每个人的钥匙 发作吧 Authorization 头曰. 页面中:
const response = await fetch(resource.url, {
headers: { Authorization: await clearlyHub.getToken() },
});
映射层( WMS, WMTS, 瓦片) 载入许多 URL 本身: 使用 Leaflet, OpenLayers 或 Cesium 选项
或添加每个请求头的插件。 钥匙持续一小时; getToken() 换个新的
时间,所以调用它 而不是保留价值。 在你的服务器上, hub.fetchAsUser(req, url)
做同样的.
关键是那个人自己 HUB 密钥: 只发送到资源 URL SELECT_DATA (清净. HUB的车
数据代理),并保留您不信任的脚本出自使用它的页面. fetchAsUser 拒绝其它 URL .
节点软件包
hub.express(), (中文(简体) ), hub.handler | 路线: /sign-in, (中文(简体) ), /callback, (中文(简体) ), /sign-out, (中文(简体) ), /session, (中文(简体) ), /open, (中文(简体) ), /answer, (中文(简体) ), /result, (中文(简体) ), /token |
onSignIn(person, { request, req }) | 每签入后即召入. 返回自己的用户ID以保留在会话中,或 { appUserId, redirectTo } 选择下一页 |
onAnswer(result, { user, data, request, req }) | 在访问浏览器前使用每个检查的答案调用, 例如要设置工作空间 . data 屏幕是被发送的;返回的屏幕是 result.app |
hub.getUser(req) | 谁签的,在自己的路线 |
hub.fetchAsUser(req, url) | 获取受保护或付费数据(从 SELECT_DATA)在你的服务器上,带有人物的钥匙. 只有URL在明显。 HUB 的数据代理 |
hub.getSubscription(hubId), (中文(简体) ), getSubscriptions() | 中心订阅了你的应用软件,或者全部 |
hub.getUserContext(req) | 签字人所在的签字中心及其作用(第2条)ADMIN 或者说 MEMBER和计划; null 当没有人签名时 |
hub.reportUsage({ request or sub, hubId, quantity }) | (b) 报告可收取费用的用途; HUB给枢纽开账单. 过 sub 很明显 你存储的HUB账户,没有直播登录 |
hub.datasets, (中文(简体) ), hub.resources, (中文(简体) ), hub.authMethods | 将数据登记在中枢, 作为签名人或您的应用程序; 参见 登记数据 |
hub.getProxyContext(req, { audience }) | 在API后面显然。 HUB 数据代理:谁打电话(sub, (中文(简体) ), subType),用于哪个中枢,与哪个角色,以及订阅. null 没有代理标题; 见 在数据代理服务器后面 |
hub.getUserToken(req), (中文(简体) ), getAppToken() | 那个人的钥匙和你的应用软件的钥匙 你自己的电话 |
在数据代理服务器后面
当你的API是一个受保护的资源,很明显。 HUB 的数据代理可以告诉它谁打电话:它增加了一个
x-oup-context 信头,一个JWT与明显签署。 HUB的钥匙. getProxyContext 检查签名,
期满,并 audience (您的资源 id), 用于此资源:
app.get('/api/flood-depth', async (req, res) => {
const context = await hub.getProxyContext(req, { audience: resourceId });
if (!context) return res.sendStatus(401);
if (context.hub.role !== 'ADMIN') return res.sendStatus(403);
// context.sub, context.subscription?.id, context.activeHub, ...
});
它扔一个 ClearlyHubError 有代码 invalid-context 当信头在那里,但没有
核实.
信头只证明如果请求真的通过代理发送,谁会打电话. 检查
代理机本身的秘密, 资源认证方法( 例如 CUSTOM_HEADER),或
仅接受代理机的流量。 代理删除一个 x-oup-context 一个客户自己送的.
现在代理只在资源认证方法有时才会添加标题
forwardSubscriptionId 继续.
你自己在钩子上. 与 hub.express()钩子得到快递 req 作为
context.req,因此他们可以同时使用自己的会话(例如快会话). HUB's: (中文(简体) )
const hub = clearlyHub<express.Request>({
// ...
onSignIn: (person, { req }) => {
const user = findOrCreateUser(person);
req!.session.userId = user.id;
return { appUserId: user.id };
},
});
它为你检查了什么: 每个屏幕的回答是Ed25519签名, 它回答一个屏幕
在此浏览器中打开一次( o)state),它被赋予你的应用和屏幕
(单位:千美元)client_id,召回 URL,动作).
如何相信一个答案: 这是他点击的瞬间 晚点再联系,
询问 getSubscription(hubId) 当用之. 谁签的 是会话的用户.
会话是用饼干加密的,所以没什么可储存的;它分出几个饼干 因为象征是巨大的。 复制的饼干在刷新令牌过期前仍然有效: 签名退出 只清除此浏览器的副本.
很明显是本地人 汉伯: 通过 urls: { screens, api, proxy, auth, issuer }; 见
examples/express/.env.example。 。 。 .
另一种路径比 /clearly-hub,例如 /auth/hub:放入三处.
- 服务器 :
clearlyHub({ basePath: '/auth/hub', ... })并安置在那里,app.use('/auth/hub', hub.express())。处理器只在下面回答basePath并建设其 从它调回URL, 所以单独安装是不够的. - 页: 1
data-base-path="/auth/hub"在脚本标签上,或clearlyHub.configure({ basePath: '/auth/hub' })。 。 。 . - 很明显 HUB: 登录客户端的回调 URL 变为
{app}/auth/hub/callback财务报告和审定财务报表{app}/auth/hub/answer,以及 转到应用程序{app}/auth/hub/sign-in。 。 。 .
登记数据
将您的应用程序的结果注册在您自己的UI的中枢中, 而不包含 REGISTER_RESOURCE 屏幕 :
数据集、其资源和认证方法保护资源使用。 只有服务器.
每通电话都从谁行动开始:要求签字人参与,或 'app',为您的
app的自有密钥( n)m2mClientId编号 :m2mClientSecret例如,在长期工作之后,没有人
签入。 没有任何人签名的请求失败 UNAUTHENTICATED。 。 。 .
const { datasetId } = await hub.datasets.create(req, {
title: 'Flood depth',
ownerHubId,
findability: 'LIMITED',
});
// Protected data: an authentication method first, then a resource behind the data proxy
const method = await hub.authMethods.create(req, ownerHubId, {
name: 'Our tile server',
type: 'CUSTOM_HEADER',
authData: { parameterName: 'X-Api-Key', parameterValue: apiKey },
});
const resource = await hub.resources.add(req, datasetId, {
name: 'Flood depth (WMS)',
format: 'wms',
sourceUrl: 'https://tiles.example.com/wms',
authenticationMethodId: method.authMethodId,
});
| 打电话 | 回返 |
|---|---|
hub.datasets.create(actor, input) | { datasetId } |
hub.datasets.update(actor, datasetId, input) | { datasetId } |
hub.datasets.delete(actor, datasetId) | 无 |
hub.datasets.get(actor, datasetId, { activeHubId? }) | 数据集,有资源 |
hub.resources.add(actor, datasetId, input) | 资源 |
hub.resources.update(actor, datasetId, resourceId, input) | 资源 |
hub.resources.delete(actor, datasetId, resourceId) | 无 |
hub.authMethods.list(actor, hubId, { type?, activeHubId? }) | 中心的方法 |
hub.authMethods.create(actor, hubId, input) | 方法 |
hub.authMethods.update(actor, hubId, authMethodId, input) | 方法 |
hub.authMethods.delete(actor, hubId, authMethodId) | 无 |
谁能. 很明显 HUB决定了 个人需要担任中心管理员(数据集和 资源:数据集的所有者中枢)。 您的应用程序的密钥有它自己的作用: 管理拥有的中枢 您的应用程序和它的子中心, 中枢成员的父母, 和编辑器 订阅您的 应用(及其子站点).
| 打电话 | 个人 | 您的应用程序: 所有器和子器 | 它的家长 | 订阅的枢纽 |
|---|---|---|---|---|
| 数据集:创建、更新、删除 | 行政 | 对 | 没有 | 对 |
| 数据集:获取、公开 | 谁都行 | 对 | 对 | 对 |
数据集:获取, LIMITED | 在一个可能找到它的中心 | 对 | 对 | 如果有人能找到的话 |
| 资源:添加、更新、删除 | 行政 | 对 | 没有 | 对 |
| 认证方法:创建、更新、删除 | 行政 | 对 | 没有 | 没有 |
| 认证方法: 列表 | 行政 | 对 | 没有 | 没有 |
将数据集移动到另一个 ownerHubId 还需要这个人或应用软件在中心。 市场
师不能作更.
很高兴知道
datasets.update财务报告和审定财务报表resources.update照创造而发送一切,你们所遗漏的 可予以清除(spatial页:1 从datasets.get(),返回形状update拿着.spatial仅存储在更新上,而不是创建上.- 受保护的资源有:
authenticationMethodId(单位:千美元)sourceUrl(地址: 代理),且无url:很明显。 HUB用它的数据代用。 打开的资源有一个url只有这个. 付费数据还有:subscriptionModelId老板枢机的计划.format很明显。 HUB的车 格式 (单位:千美元)wms, (中文(简体) ),wfs, (中文(简体) ),wmts, (中文(简体) ),tilejson, (中文(简体) ),api,...). URL需要一个域:localhost实值 拒绝, 使用lvh.me。 。 。 . authData拥有秘密 很明显 HUB从不还的,而且update替换全部. 每栏type数字 :BASIC_AUTHusername, (中文(简体) ),password· ;URL_PARAMETER财务报告和审定财务报表CUSTOM_HEADERparameterName, (中文(简体) ),parameterValue· ;ISHARE_AUTH_METHODtokenEndpoint, (中文(简体) ),serviceProviderEORI, (中文(简体) ),entitledPartyEORI· ;JWT_ENDPOINTtokenEndpoint, (中文(简体) ),username, (中文(简体) ),password, (中文(简体) ),usernameField, (中文(简体) ),passwordField(和accessTokenProperty, (中文(简体) ),refreshTokenProperty(三);S3s3AccessKeyId, (中文(简体) ),s3SecretAccessKey· ;OAUTH2_CLIENT_CREDENTIALStokenEndpoint, (中文(简体) ),clientId, (中文(简体) ),clientSecret(和accessTokenProperty, (中文(简体) ),secretAsHeader, (中文(简体) ),scope) (中文(简体) ). 类型(AuthDataByType)说同.- 删除数据集删除其资源并取消对其付费资源的订阅.
- 错误是
ClearlyHubError很明显 HUB的讯息和code(单位:千美元)BAD_USER_INPUT, (中文(简体) ),FORBIDDEN, (中文(简体) ),UNAUTHENTICATED) (中文(简体) ). SDK在发送前会检查它能做的,有相同的代码.
未覆盖( 尚未覆盖)
- 建立自己的工作空间或租户:用手、需要批准的计划或
onAnswer页:1SELECT_SUBSCRIPTION。 。 。 . - 其他服务器语言(.NET, Python,.):浏览器包与任意 后端可以回答同样的路线. 联系我们 支持@ futureinsight.nl 我们会帮忙的 带着你的.
正在研究这项回购
npm install
npm run build # both packages
npm test # vitest
npm run typecheck
npm run lint
npm run example # examples/express on http://localhost:5175 (copy .env.example to .env first)