mcpField
P
ping-orchestration-javascript-sdk

ping-orchestration-javascript-sdk

github.com/pingidentity安全148 次安装13 周前更新
代码仓库

关于 ping-orchestration-javascript-sdk

为 Web 应用集成 Ping Orchestration JavaScript SDK 认证提供引导式技能。它收集流程与应用配置,再转交 React Journey 或 DaVinci 技能,或生成 OIDC 及框架无关的接入代码。

主要功能

  1. 01Journey、DaVinci 与 OIDC 流程指引
  2. 02三步配置向导
  3. 03React 技能交接
  4. 04框架检测与路由
  5. 05SDK 安装及构建工具指引

适用场景

  1. 01在 React 应用中配置 Ping Journey 认证
  2. 02使用统一配置接入 DaVinci 登录
  3. 03生成集中式 OIDC 登录接入代码
  4. 04将 SDK 接入适配到占位框架

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pingidentity/ping-sdk-agent-skills --skill ping-orchestration-javascript-sdk

安装后在 Claude Code 中输入/ping-orchestration-javascript-sdk确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
.gitignore.template
oidc-centralized-reference.md
assets/angular/
README.md
assets/react/
.env.template
oidc-app.jsx.template
oidc-callback.jsx.template
oidc-home.jsx.template
oidc-login.jsx.template
assets/vanilla/
README.md
assets/vue/
README.md
references/
sdk-packages.md

详细介绍

Ping JavaScript SDK

使用 Ping Orchestration JavaScript SDK(@forgerock/journey-client、@forgerock/davinci-client、@forgerock/oidc-client)构建 Web 应用的首选入口。支持三种身份验证流程:

  • Journey — 针对 PingAM 或 PingOne AIC 的基于回调的身份验证 → 委托给 ping-orchestration-reactjs-journey-sdk
  • DaVinci — 针对 PingOne DaVinci 的基于收集器的身份验证 → 委托给 ping-orchestration-reactjs-davinci-sdk
  • OIDC centralized login — OAuth2 授权码流程(浏览器重定向)→ 内联处理

运行三步向导(W1 → W2 → W3),以确定流程类型、检测框架、收集通用配置,然后交接或生成代码。

框架注册表

此表是框架路由的唯一事实来源。决策树会引用其中的 Status。添加新框架:将其状态从 placeholder 更改为 active,添加委托技能名称,填写 OIDC 模板目录,并在“构建工具配置”小节中添加任何特定于构建工具的指导。

框架Journey 委托项DaVinci 委托项OIDC 模板状态
Reactping-orchestration-reactjs-journey-sdkping-orchestration-reactjs-davinci-sdkassets/react/active
Angular——assets/angular/placeholder
Vue——assets/vue/placeholder
Vanilla JS——assets/vanilla/placeholder

向导

每次调用此技能时,若未提供 create-sample 参数,都要运行以下三个步骤。

W1 — 流程类型

询问:

你要构建哪种流程?

  1. Journey — 针对 PingAM 或 PingOne AIC 的基于回调的身份验证
  2. DaVinci — 针对 PingOne DaVinci 的基于收集器的身份验证
  3. OIDC centralized login — OAuth2/OIDC 授权码流程(浏览器重定向,无需自定义 UI)
W1b — 框架检测

收集配置前,检测或询问用户使用的框架。

如果存在 package.json,运行:

grep -E '"(react|vue|@angular/core|vite)"' package.json
  • 找到 react → 检测到 React → 继续执行 W2。
  • 找到 vue 或 @angular/core → 宣布这是占位框架,并提供选项:

    “专用的 ping-orchestration-vue-sdk / ping-orchestration-angular-sdk 技能即将推出。我可以:

    1. 生成框架无关的 SDK 接入代码 — 客户端初始化、令牌交换和路由守卫伪代码,你可以根据框架的惯用模式进行调整。
    2. 转到 React 技能(ping-orchestration-reactjs-journey-sdk / ping-orchestration-reactjs-davinci-sdk),将其作为可移植的参考实现。

    你希望选择哪一种?”

    • 如果用户选择选项 1 → 继续执行 W2,然后使用下方的通用(占位框架)路径。
    • 如果用户选择选项 2 → 继续执行 W2,并委托给 React 技能。
  • 找到 react-native(单独检查)→ 告知用户 ping-orchestration-react-native-sdk 即将推出;目前没有临时替代方案。
  • 未找到任何内容,或不存在 package.json → 询问:“你使用的是哪种 JavaScript 框架?”列出框架注册表中的活跃框架。如果用户指定占位框架,提供上述相同的两个选项。
W2 — 共享配置

收集以下参数。跳过用户已在消息中提供的参数。

参数适用于备注
wellknown所有流程完整的 OIDC 发现 URL,以 .well-known/openid-configuration 结尾
clientId所有流程在 PingOne/AIC 中注册的 OAuth 客户端 ID
redirectUri所有流程必须与注册值完全一致——包含 /callback 路径后缀
scope所有流程以空格分隔;必须包含 openid
appName所有流程用于项目/目录命名
journeyName仅 Journey身份验证树名称(例如,Login)
acrValues仅 DaVinci/OIDC可选的 ACR 值字符串

进入 W3 前的验证:

  • wellknown 必须以 .well-known/openid-configuration 结尾
  • scope 必须包含 openid——如果缺少,请将其添加并告知用户
  • redirectUri 必须是以 http:// 或 https:// 开头的绝对 URL
W3 — 确认并移交

显示摘要表:

参数值
流程<journey | davinci | oidc-centralized>
框架<React>
Well-known URL<wellknown>
客户端 ID<clientId>
重定向 URI<redirectUri>
Scope<scope>
应用名称<appName>
Journey 名称 (仅 Journey)<journeyName>
ACR 值 (DaVinci/OIDC,若已提供)<acrValues>

询问:“看起来正确吗?要继续吗?”

确认后:

  • Journey(活动框架) → 通过 Skill 工具,从 Framework Registry 调用 Journey delegate。在调用上下文中传入收集到的配置。不要内联该 skill 的内容。注意:Journey delegate 使用自己的环境变量命名方式(VITE_WELLKNOWN_URL、VITE_WEB_OAUTH_CLIENT 等)——delegate 会处理这些;请传入 W2 中的逻辑值。
  • DaVinci(活动框架) → 通过 Skill 工具,从 Framework Registry 调用 DaVinci delegate。传入收集到的配置。不要内联该 skill 的内容。注意:DaVinci delegate 使用自己的环境变量命名方式(VITE_CLIENT_ID、VITE_DISCOVERY_ENDPOINT 等)——请传入 W2 中的逻辑值。
  • OIDC centralized(活动框架) → 读取 assets/oidc-centralized-reference.md,然后继续下方的 OIDC Centralized Login 部分。使用框架 OIDC Templates 目录中的模板。
  • 任何流程(占位框架,通用路径) → 继续下方的 Generic (Placeholder Framework) Path 部分。

通用(占位框架)路径

当 Framework Registry 中用户的框架为 placeholder,且用户在 W1b 中选择了与框架无关的 SDK 接线方式时,使用此路径。SDK 软件包是纯 JavaScript,不依赖任何框架——此路径提供集成接线方式,无需使用特定框架的组件渲染。

生成内容

针对每种流程类型,生成一个用户可适配到其框架中的集成模块:

Journey:

import { journey, callbackType } from '@forgerock/journey-client';
import { oidc } from '@forgerock/oidc-client';

// 1. Initialise OIDC client (for token management after Journey completes)
const oidcClient = await oidc({ config: {
  serverConfig: { wellknown: '<wellknown>' },
  clientId: '<clientId>',
  redirectUri: '<redirectUri>',
  scope: '<scope>',
} });

// 2. Start Journey
const client = await journey({
  serverConfig: { wellknown: '<wellknown>' },
  journeyName: '<journeyName>',
});

let step = await client.start();

// 3. Loop: render callbacks, collect input, submit
while (step.type === 'Step') {
  for (const cb of step.callbacks) {
    // Inspect cb.type (callbackType.NameCallback, callbackType.PasswordCallback, etc.)
    // Collect user input and call cb.setInput(value) or equivalent setter
  }
  step = await client.next(step);
}

// 4. Handle outcome
if (step.type === 'SuccessStep') {
  // Journey complete — tokens available via oidcClient.token.get()
} else {
  // step.type === 'FailureStep' — display error
}

DaVinci:

import { davinci } from '@forgerock/davinci-client';

const client = await davinci({
  serverConfig: { wellknown: '<wellknown>' },
  clientId: '<clientId>',
  redirectUri: '<redirectUri>',
  scope: '<scope>',
});

let node = await client.start();

// Loop: render collectors, collect input, submit
while (node.status === 'continue') {
  const collectors = node.client.collectors;
  for (const collector of collectors) {
    // Inspect collector.type (TextCollector, PasswordCollector, SubmitCollector, etc.)
    // Set value: collector.value = userInput;
  }
  node = await client.next();
}

if (node.status === 'success') {
  // Auth complete — session established
} else {
  // node.status === 'error' — display node.error
}

OIDC centralized:

import { oidc } from '@forgerock/oidc-client';

const CONFIG = {
  serverConfig: { wellknown: '<wellknown>' },
  clientId: '<clientId>',
  redirectUri: '<redirectUri>',
  scope: '<scope>',
};

const client = await oidc({ config: CONFIG });

// Login: redirect to authorization endpoint
const url = await client.authorize.url();
window.location.href = url;

// Callback page: exchange code for tokens
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
if (code && state) {
  await client.token.exchange(code, state);
  window.location.replace('/');
}

// Check auth state
const tokens = await client.token.get();

// Logout
await client.user.logout();
应包含的指导

生成集成模块后:

  1. 说明哪些部分对应框架相关逻辑(渲染循环 → 组件树;身份验证检查 → 路由守卫;回调页面 → 专用路由)。
  2. 指向 React delegate skill,作为可供研究的完整参考实现。
  3. 如果用户分享其应用结构,可提供帮助,将该模块接入其特定框架的模式中。

共享设置指南

本节适用于所有流程类型和框架。请在委派或生成代码前提供此指南。

SDK 设置(所有框架)

完整的软件包参考:references/sdk-packages.md

仅安装流程所需的软件包:

# Journey
npm install @forgerock/journey-client @forgerock/oidc-client

# DaVinci
npm install @forgerock/davinci-client
# Add @forgerock/oidc-client if you need token management beyond DaVinci's built-in session

# OIDC centralized login
npm install @forgerock/oidc-client

# Optional add-ons (any flow)
npm install @forgerock/protect       # PingOne Protect / behavioral signals
npm install @forgerock/device-client # Device profile, OATH, Push, WebAuthn management
常见问题(SDK 级别)
  • redirectUri 不匹配:该值必须与 PingOne/AIC 中注册的值完全一致——尾部斜杠、端口号和路径都很重要。
  • 缺少 openid scope:@forgerock/oidc-client 要求 scope 中包含 openid,否则令牌交换会失败。
  • CORS:well-known 端点必须在服务器的 CORS 策略中包含应用的来源。如果出现预检失败,请检查 PingOne/AIC 的 CORS 设置。
  • wellknown 与 serverConfig:新 SDK(@forgerock/journey-client v2+)仅使用 wellknown。不支持旧版 serverConfig.baseUrl。
构建工具配置

应用与检测到的框架相匹配的部分。每个项目仅适用一部分。

占位框架说明(Angular、Vue、Vanilla JS): 这些框架的完整技能支持尚未启用。以下部分介绍正确的构建工具惯例,以便你在使用通用占位框架路径时正确配置环境。占位框架不会生成 OIDC 模板——请手动调整这些模式。

React + Vite

环境变量使用 VITE_ 前缀(Vite 要求使用此名称,才能在客户端公开):

VITE_PING_WELLKNOWN=https://auth.example.com/am/oauth2/alpha/.well-known/openid-configuration
VITE_PING_CLIENT_ID=my-app
VITE_PING_REDIRECT_URI=http://localhost:5173/callback
VITE_PING_SCOPE=openid profile
# Journey only:
VITE_PING_JOURNEY_NAME=Login
# DaVinci/OIDC optional:
VITE_PING_ACR_VALUES=

参考:assets/react/.env.template

Vite 特有问题:

  • 只有带 VITE_ 前缀的变量才会公开到浏览器包中。仅供服务器使用的机密信息必须不带此前缀。
  • 不要添加包含内联 oidc().token.exchange() 脚本的静态 public/callback.html。 当 @forgerock/oidc-client 调用 authorize.background() 进行静默令牌续期时,它会打开一个隐藏的 iframe,访问授权端点并重定向回 redirectUri。如果该 URL 上的静态脚本实例化了第二个 OIDC 客户端并开始交换代码,就会劫持 iframe,导致 iframe 超时错误。请改为在 React 应用中将回调作为普通路由处理(参见 oidc-callback.jsx.template)。
Angular CLI

环境变量放在 src/environments/environment.ts 中:

export const environment = {
  pingWellknown: 'https://auth.example.com/am/oauth2/alpha/.well-known/openid-configuration',
  pingClientId: 'my-app',
  pingRedirectUri: 'http://localhost:4200/callback',
  pingScope: 'openid profile',
  // Journey only:
  pingJourneyName: 'Login',
};

Angular 特有说明:

  • 使用 environment.ts / environment.prod.ts 配置——Angular 不会向浏览器公开 process.env。
  • 回调路由是普通的 Angular 路由组件——由于 Angular 的路由器会处理回调,因此无需使用静态 HTML 变通方案。
Vue CLI / Vite

环境变量使用与你的构建工具相匹配的前缀:

  • Vite → VITE_ 前缀(与上文 React + Vite 相同)
  • Vue CLI(webpack) → VUE_APP_ 前缀
VUE_APP_PING_WELLKNOWN=https://auth.example.com/am/oauth2/alpha/.well-known/openid-configuration
VUE_APP_PING_CLIENT_ID=my-app
VUE_APP_PING_REDIRECT_URI=http://localhost:8080/callback
VUE_APP_PING_SCOPE=openid profile

使用 process.env.VUE_APP_*(Vue CLI)或 import.meta.env.VITE_*(Vite)访问。

Vanilla JS / 其他

没有框架专用的环境变量惯例。可选择适合项目的任意方式:

  • 导出常量的 config.js 文件
  • 在构建时通过 dotenv 加载 .env
  • 在零构建设置中使用内联 <script> 变量

create-sample 命令

/ping-orchestration-javascript-sdk create-sample "<description>"

步骤:

  1. 分析描述,确定流程类型(journey / davinci / oidc-centralized)和框架。
  2. 如果流程类型不明确,提出一个澄清问题。
  3. 如果框架不是 React,且无法从项目中检测到,请询问用户。
  4. 从 W2 中收集描述无法推断出的所有缺失必需参数。
  5. 如果框架在 Framework Registry 中标记为 active:
    • Journey → 使用 Skill 工具,通过预填配置调用 Journey delegate。
    • DaVinci → 使用 Skill 工具,通过预填配置调用 DaVinci delegate。
    • OIDC centralized → 读取 assets/oidc-centralized-reference.md,并从框架的 OIDC Templates 目录中生成模板,同时替换占位符。
  6. 如果框架标记为 placeholder → 使用 Generic(Placeholder Framework)路径。

模板占位符(仅适用于 OIDC centralized):

占位符值
PLACEHOLDER_APP_NAMEappName
PLACEHOLDER_WELLKNOWNwellknown
PLACEHOLDER_CLIENT_IDclientId
PLACEHOLDER_REDIRECT_URIredirectUri
PLACEHOLDER_SCOPEscope
PLACEHOLDER_ACR_VALUESacrValues — 如果未提供,则省略该行

OIDC Centralized 登录

直接内联处理,无需委派。直接使用 @forgerock/oidc-client。完整 API 参考:assets/oidc-centralized-reference.md。

流程
  1. 用户进入登录页面 → 调用 client.authorize.url() 生成授权 URL → 重定向浏览器。
  2. 用户在 PingOne/AIC 上完成身份验证 → 浏览器重定向回 redirectUri。
  3. 回调页面从 URL 中读取 code 和 state → 调用 client.token.exchange(code, state) → 存储令牌。
  4. 应用调用 client.token.get() 读取令牌 → 用户已通过身份验证,渲染受保护内容。
  5. 后台续期:调用 client.token.get({ backgroundRenew: true }),通过隐藏的 iframe 保持会话有效。
  6. 登出:调用 client.user.logout() → 撤销访问令牌并结束服务器上的会话。
客户端初始化
import { oidc } from '@forgerock/oidc-client';

const CONFIG = {
  serverConfig: {
    wellknown: import.meta.env.VITE_PING_WELLKNOWN,
  },
  clientId: import.meta.env.VITE_PING_CLIENT_ID,
  redirectUri: import.meta.env.VITE_PING_REDIRECT_URI,
  scope: import.meta.env.VITE_PING_SCOPE,
  // acrValues: import.meta.env.VITE_PING_ACR_VALUES, // uncomment if needed
};

const client = await oidc({ config: CONFIG });
令牌交换(回调页面)
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');

if (code && state) {
  await client.token.exchange(code, state);
  window.location.replace('/');  // redirect to home after successful exchange
}
路由守卫模式

所有框架的路由守卫逻辑都相同,只有组件包装器会变化。

核心逻辑(与框架无关):

async function checkAuth(client) {
  const tokens = await client.token.get();
  if (!tokens) {
    const url = await client.authorize.url();
    window.location.href = url;
    return null;
  }
  return tokens;
}

React 包装器:

import { useEffect, useState } from 'react';

export function ProtectedRoute({ children }) {
  const [isAuthenticated, setIsAuthenticated] = useState(null);

  useEffect(() => {
    client.token.get().then((tokens) => {
      setIsAuthenticated(!!tokens);
    });
  }, []);

  if (isAuthenticated === null) return <div>Loading…</div>;
  if (!isAuthenticated) {
    client.authorize.url().then((url) => { window.location.href = url; });
    return null;
  }
  return children;
}

对于其他框架,使用相同的 checkAuth 逻辑,根据框架的守卫机制调整包装器(例如 Angular CanActivate、Vue beforeEach 导航守卫等)。

模板

当流程类型为 oidc-centralized 时,生成以下文件。从 Framework Registry 的 OIDC Templates 列中指定的活动框架子目录读取模板(例如,React 对应 assets/react/)。替换占位符,并将文件写入用户的项目目录。

React(assets/react/):

模板文件输出路径用途
assets/react/.env.template.env环境变量(Vite VITE_ 前缀)
assets/react/oidc-app.jsx.templatesrc/App.jsx包含 OIDC 上下文和受保护路由的应用外壳
assets/react/oidc-login.jsx.templatesrc/pages/Login.jsx登录触发器(authorize.url() → 重定向)
assets/react/oidc-callback.jsx.templatesrc/pages/Callback.jsx代码交换处理器(通过 React 组件调用 token.exchange)
assets/react/oidc-home.jsx.templatesrc/pages/Home.jsx包含登录 CTA、用户信息和登出功能的主页

其他框架: 当其 OIDC Templates 目录中包含模板时,遵循相同模式——从框架的 assets/<framework>/ 目录读取。

常见问题(OIDC)
  • state 不匹配:切勿手动构造授权 URL。始终使用 client.authorize.url()——它会自动生成并存储 state 和 code_verifier(PKCE)。调用 token.exchange 时,如果传入的 state 与已存储的状态不匹配,就会抛出 state_mismatch。
  • 后台续期需要允许 iframe:backgroundRenew: true 会打开一个指向授权端点的隐藏 iframe。如果 CSP 阻止了 frame-src,续期会静默失败。请将 PingOne/AIC 域名添加到 frame-src。
  • PKCE 始终启用:@forgerock/oidc-client 默认使用 PKCE,且不提供切换选项。OAuth 客户端注册必须启用 PKCE(或将其设为可选)。

评论

支持 Markdown