关于 ping-orchestration-reactjs-journey-sdk
用于在 React 单页应用中构建 Ping Orchestration JavaScript SDK 认证流程的技能。可生成完整示例应用或现有应用所需的集成文件,包含 Journey 流程处理和受保护路由。
主要功能
- 01生成 React 示例应用
- 02为现有应用生成集成文件
- 03用自定义 Hook 管理 Journey 步骤
- 04渲染各类回调组件
- 05管理 OIDC 状态与受保护路由
适用场景
- 01演示 PingAM 或 AIC 认证
- 02为 React SPA 添加 Journey 登录或注册
- 03在现有应用中集成增强认证
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pingidentity/ ping-sdk-agent-skills --skill ping-orchestration-reactjs-journey-sdk安装后在 Claude Code 中输入/ping-orchestration-reactjs-journey-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/.env.template.gitignore.templateboolean.jsx.templatecallback.html.templatechoice.jsx.templateconfirmation.jsx.templateconstants.js.templatedevice-profile.jsx.templateform.jsx.templatehidden-value.jsx.templatehome.jsx.templateindex.html.templateindex.jsx.templatejourney.hook.js.templatekba.jsx.templatelogin.jsx.templatelogout.jsx.templatemetadata.jsx.templatenumber.jsx.templateoidc.context.js.templatepackage.json.templatepassword.jsx.templatepolling-wait.jsx.templateprotect-evaluation.jsx.templateprotect-initialize.jsx.templaterecaptcha-enterprise.jsx.templaterecaptcha.jsx.templateredirect.jsx.templateregister.jsx.templateroute.jsx.template详细介绍
使用 Ping Orchestration JavaScript SDK 进行 ReactJS 身份验证
使用 Ping Orchestration JavaScript SDK(Journey),在 ReactJS 单页应用中搭建完整的身份验证流程。
元数据
| 字段 | 值 |
|---|---|
| 语言 | JavaScript (JSX) |
| 框架 | React 18+、React Router 6+、Vite |
| SDK | Ping Orchestration JavaScript SDK(@forgerock/journey-client、@forgerock/oidc-client) |
| 模式 | 函数组件、自定义 Hook、Context API |
| Node.js | >= 18.12.0 |
概述
此技能可为 ReactJS 单页应用添加完整的身份验证流程。它使用 Ping Identity Orchestration JavaScript SDK(Journey 客户端),通过 PingOne Advanced Identity Cloud (AIC) 或 PingAM 验证用户身份。
实现内容包括:
- 通过 OIDC well-known 端点发现配置 Journey 客户端
- 设置 OIDC 客户端以进行 OAuth 2.0 令牌交换、续期和撤销
- 用于管理分步身份验证流程的自定义 React Hook(
useJourney) - 使用专用 React 组件动态渲染各类回调
- 使用 React Router 处理受保护路由
- 基于 Context 管理身份验证状态
- 登录、注册和登出流程
- 通过
oidcClient.user.info()显示用户资料,并可选择启用编辑界面 - 成功、错误和失败处理
使用场景
- 示例应用 — 从头构建一个完整且具有主题风格的 ReactJS 应用,以演示 Ping Orchestration JavaScript SDK 如何与 PingAM 和 AIC 配合使用。该应用包含所有 SDK 集成文件,以及带导航、样式化视图、用户资料页面和受保护内容的完整 UI。Agent 应生成
package.json、vite.config.js、index.html、CSS 样式表以及所有视图和组件。 - 集成到现有应用 — 将 Ping Orchestration JavaScript SDK 集成到现有 ReactJS SPA 中,以添加身份验证、增强身份验证或 SDK 支持的任何基于 Journey/Tree 的流程。Agent 应仅生成 SDK 集成文件(常量、Context、Hook、表单、回调、受保护路由),并指导用户将其接入现有路由器和布局。
前置条件
1. npm 依赖项
在 React 项目中安装以下软件包:
npm install @forgerock/journey-client @forgerock/oidc-client react react-dom react-router-dom
其他功能的可选依赖项:
# PingOne Protect integration (threat signals / risk evaluation)
npm install @forgerock/protect
完整示例请参阅 package.json 模板。
2. Vite 配置
此技能使用 Vite 作为构建工具。推荐配置请参阅 vite.config.js 模板。
npm install --save-dev vite @vitejs/plugin-react
3. CORS 配置(PingAM / AIC)
在 PingAM 或 AIC 租户中配置 CORS:
| 设置 | 值 |
|---|---|
| 允许的源 | https://localhost:8443(或你的应用 URL) |
| 允许的方法 | GET、POST |
| 允许的标头 | Content-Type、X-Requested-With、X-Requested-Platform、Accept-API-Version、Authorization |
| 允许凭据 | 已启用 |
4. OAuth 2.0 客户端注册
在 PingAM / AIC 中创建一个公开(SPA) OAuth 客户端:
| 设置 | 值 |
|---|---|
| 客户端类型 | 公开 |
| 授权类型 | Authorization Code |
| 令牌端点身份验证方法 | none |
| 范围 | openid profile email(最低要求) |
| 重定向 URI | 应用的回调 URL(例如 https://localhost:8443/callback.html) |
| 隐式授权 | 已启用 |
必需配置
**Agent 指令:**生成任何文件之前,请先向用户收集以下值。
**第 0 步——确定使用场景:**询问用户想要 示例应用(完整脚手架,包括
package.json、vite.config.js、index.html、CSS、导航和经过样式设计的视图),还是 集成到现有应用(仅生成 SDK 集成文件:常量、上下文、钩子、表单、回调、受保护路由)。这会影响后续步骤中要生成的文件。在一个提示中一次性询问所有
required参数。对于可选参数,显示默认值,并询问用户是否要覆盖。所有必需参数都有非空值之前,不要继续第 1 步。
要收集的参数
| 参数 | 必需 | 默认值 | 描述 |
|---|---|---|---|
wellknownUrl | 是 | — | 完整的 OIDC well-known 端点 URL(例如,https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration) |
clientId | 是 | — | 在 PingAM / AIC 中为此 Web 应用注册的 OAuth 2.0 Client ID |
scope | 是 | openid profile email | 以空格分隔的 OAuth 2.0 请求范围 |
redirectUri | 否 | http://localhost:<appPort>/callback.html | 在 PingAM / AIC 中注册的 OAuth 2.0 重定向 URI |
journeyLogin | 否 | Login | 要调用的登录 Journey/Tree 名称 |
journeyRegister | 否 | Registration | 要调用的注册 Journey/Tree 名称 |
appPort | 否 | 8443 | 本地开发服务器端口 |
建议的提示词
Before I get started, I want to confirm — are you wanting me to help you create a sample app or
integrate with your existing single-page app?
Before I generate the files, I need a few details about your PingAM / AIC setup:
1. Well-known URL — What is your OIDC well-known endpoint URL?
e.g. https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration
2. Client ID — What is the OAuth 2.0 Client ID for this web app?
3. Scopes — Which OAuth 2.0 scopes? (default: openid profile email)
4. Redirect URI — What is the redirect URI? (default: http://localhost:8443/callback.html)
5. Login Journey — Which Journey/Tree for login? (default: Login)
6. Register Journey — Which Journey/Tree for registration? (default: Registration)
7. App Port — Which port for local dev? (default: 8443)
验证规则
wellknownUrl必须以https://开头,并以/.well-known/openid-configuration结尾。clientId不能为空。- 如果
scope不包含openid,请自动将其添加到开头,并提醒用户。 redirectUri必须是有效 URL,且以https://或http://localhost开头。- 如果用户提供的
redirectUri端口与appPort不同,请提醒用户——这两个端口可能需要保持一致。
Well-known URL 构造指南
**Agent 指令:**用户通常提供的是 AM 基础 URL(例如,
https://your-tenant.forgeblocks.com/am),而不是完整的 well-known URL。如果提供的 URL 不以/.well-known/openid-configuration结尾:
- 询问用户使用哪个 realm(AIC 中常见的是
alpha或bravo)。- 按以下格式构造 well-known URL:
<baseUrl>/oauth2/<realm>/.well-known/openid-configuration- 构造前删除基础 URL 末尾的任何
/。- 继续之前,请与用户确认构造出的 URL。
示例:
- 用户提供:
https://openam-myco.forgeblocks.com/am- Agent 询问:“使用哪个 realm?(常见的是
alpha或bravo)”- 用户回答:
alpha- Agent 构造:
https://openam-myco.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration- Agent 确认:“我将使用此 URL 作为 well-known URL——这样正确吗?”
实施步骤
第 1 步——配置环境变量
在项目根目录创建 .env 文件。请参阅 .env 模板。
另外添加 .gitignore,防止机密信息和构建产物进入版本控制。请参阅 .gitignore 模板。
**Agent 指令:**将所有
<parameter>占位符替换为上文收集的值。
VITE_WELLKNOWN_URL=<wellknownUrl>
VITE_WEB_OAUTH_CLIENT=<clientId>
VITE_SCOPE=<scope>
VITE_PORT=<appPort>
VITE_JOURNEY_LOGIN=<journeyLogin>
VITE_JOURNEY_REGISTER=<journeyRegister>
VITE_REDIRECT_URI=<redirectUri>
VITE_DEBUGGER_OFF=true
步骤 2 — 创建配置常量
创建 constants.js,集中管理 SDK 配置。请参阅 constants.js 模板。
SDK 配置只需要 wellknown URL——Journey 客户端会从 well-known 文档中自动推导 baseUrl、authenticate 和 sessions 端点。
export const WELLKNOWN_URL = import.meta.env.VITE_WELLKNOWN_URL;
export const WEB_OAUTH_CLIENT = import.meta.env.VITE_WEB_OAUTH_CLIENT;
export const SCOPE = import.meta.env.VITE_SCOPE;
export const REDIRECT_URI = import.meta.env.VITE_REDIRECT_URI || `${window.location.origin}/callback.html`;
export const CONFIG = {
clientId: WEB_OAUTH_CLIENT,
redirectUri: REDIRECT_URI,
scope: SCOPE,
serverConfig: {
wellknown: WELLKNOWN_URL,
},
};
注意:
VITE_REDIRECT_URI允许通过环境变量配置重定向 URI。 如果未设置,默认值为${window.location.origin}/callback.html。这一点很重要,因为 本地开发可能使用http://,而生产环境使用https://,并且重定向 URI 必须与在 PingAM / AIC 中注册的 URI 完全匹配。
有关所有配置选项,请参阅 SDK 软件包参考 中的 @forgerock/journey-client 部分。
步骤 3 — 创建 OIDC 上下文提供程序
创建 oidc.context.js,用于管理应用中的身份验证状态。请参阅 oidc.context.js 模板。
OIDC 上下文:
- 在应用挂载时初始化 OIDC 客户端
- 检查是否存在现有令牌(会话持久化)
- 向所有组件提供
isAuthenticated、oidcClient和用户信息 - 通过撤销令牌并清除状态来处理登出
import { createContext } from 'react';
import { oidc } from '@forgerock/oidc-client';
export const OidcContext = createContext();
export function useInitOidcState(config) {
// Initialize OIDC client and check for existing session
// Returns [state, methods] for context consumption
}
有关 API 文档,请参阅 SDK 软件包参考 中的 @forgerock/oidc-client 部分,以及完整的 OIDC 集中式参考。
步骤 4 — 创建 Journey Hook
创建 journey.hook.js——用于管理 Journey 身份验证流程的核心自定义 Hook。请参阅 journey.hook.js 模板。
主要职责:
- 使用共享的
CONFIG初始化 Journey 客户端 - 启动新的 Journey(或在重定向后恢复)
- 处理步骤提交并进入下一个节点
- 收到
LoginSuccess时,通过 OIDC 客户端将会话交换为 OAuth 令牌 - 收到
LoginFailure时,提取错误消息并重新启动 Journey - 返回用于渲染的当前步骤以及用于提交表单的方法
import { journey, callbackType } from '@forgerock/journey-client';
export default function useJourney({ formMetadata, resumeUrl }) {
// Returns [state, methods]
// state: { formFailureMessage, renderStep, submittingForm, user }
// methods: { setSubmissionStep, setSubmittingForm, redirect }
}
有关客户端 API 详情,请参阅 SDK 软件包参考 中的 @forgerock/journey-client 部分。
步骤 5 — 创建 Journey 表单组件
创建 form.jsx——用于渲染当前 Journey 步骤回调的主表单组件。请参阅 form.jsx 模板。
表单:
- 使用
useJourney获取当前步骤和提交方法 - 将步骤中的每个回调映射到相应的 React 组件
- 通过设置提交步骤来处理表单提交
- 收到
LoginSuccess时跳转离开
import { callbackType } from '@forgerock/journey-client';
export default function Form({ action, followUp, topMessage }) {
// Maps callbacks to components and handles form lifecycle
}
有关支持的回调实现的完整列表,请参阅此技能 assets/ 目录中的回调资源。
步骤 6 — 创建回调组件
为每种回调类型创建单独的 React 组件。请参阅回调组件模板。
@forgerock/journey-client 支持的所有回调类型:
| 回调类型 | 组件 | 描述 |
|---|---|---|
NameCallback | Text | 用于输入用户名的文本字段 |
ValidatedCreateUsernameCallback | Text | 带策略强制校验的用户名输入字段 |
StringAttributeInputCallback | Text | 通用字符串属性(电子邮件、姓名等) |
TextInputCallback | TextInput | 通用文本输入字段 |
PasswordCallback | Password | 带可见性切换的密码输入字段 |
ValidatedCreatePasswordCallback | Password | 带策略强制校验的密码输入字段 |
BooleanAttributeInputCallback | Boolean | 用于布尔属性的复选框开关 |
NumberAttributeInputCallback | NumberInput | 用于数字属性的数字输入字段 |
ChoiceCallback | Choice | 单选下拉列表 |
ConfirmationCallback | Confirmation | 操作选项(提交 / 取消) |
SelectIdPCallback | SelectIdP | 社交 / 外部身份提供商选择 |
KbaCreateCallback | Kba | 安全问题和答案 |
TermsAndConditionsCallback | TermsConditions | 条款接受复选框 |
TextOutputCallback | TextOutput | 显示服务端消息(信息、警告、错误) |
SuspendedTextOutputCallback | SuspendedTextOutput | 已暂停的流程消息(魔法链接 / 电子邮件验证) |
PollingWaitCallback | PollingWait | 自动前进的等待步骤(无需用户交互) |
RedirectCallback | Redirect | 用于外部身份验证的浏览器重定向(社交登录、SAML) |
DeviceProfileCallback | DeviceProfile | 自动收集设备元数据并提交 |
HiddenValueCallback | HiddenValue | 非可视 — 在客户端和服务端之间传递内部状态 |
MetadataCallback | Metadata | 非可视 — 将服务端元数据传递给客户端 |
ReCaptchaCallback | ReCaptcha | Google reCAPTCHA v2 小组件 |
ReCaptchaEnterpriseCallback | ReCaptchaEnterprise | Google reCAPTCHA Enterprise 小组件 |
PingOneProtectInitializeCallback | ProtectInitialize | 初始化 PingOne Protect 威胁信号收集 |
PingOneProtectEvaluationCallback | ProtectEvaluation | 收集并提交 PingOne Protect 威胁信号 |
| WebAuthn (FIDO2) | WebAuthnComponent | FIDO2/Passkey 注册和身份验证 |
每个组件都遵循以下模式:
- 获取回调中的显示值(例如,
callback.getPrompt()) - 渲染适当的表单元素
- 将用户输入设置回调(例如,
callback.setInputValue(value))
注意: 自动前进的回调(
PollingWaitCallback、DeviceProfileCallback、RedirectCallback、ReCaptchaCallback、ReCaptchaEnterpriseCallback、PingOneProtectInitializeCallback、PingOneProtectEvaluationCallback)无需用户交互 — 完成操作后会自动提交此步骤。
步骤 7 — 创建登录和注册视图
创建 login.jsx 和 register.jsx 视图。请参阅 login.jsx 模板和 register.jsx 模板。
// login.jsx — Renders the Form component with the login journey
export default function Login() {
return <Form action={{ type: 'login' }} />;
}
// register.jsx — Renders the Form component with the registration journey
export default function Register() {
return <Form action={{ type: 'register' }} />;
}
步骤 8 — 创建注销视图
创建 logout.jsx。请参阅 logout.jsx 模板。
注销时使用 OIDC 上下文来撤销令牌并清除会话:
import { useContext, useEffect } from 'react';
import { OidcContext } from '../context/oidc.context';
export default function Logout() {
const [, { setAuthentication }] = useContext(OidcContext);
useEffect(() => { setAuthentication(false); }, []);
return <p>Logging out...</p>;
}
步骤 9 — 创建受保护路由和路由器
创建 ProtectedRoute 组件和应用路由器。请参阅 route.jsx 模板和 router.jsx 模板。
// Protected route — redirects to /login if not authenticated
export function ProtectedRoute({ children }) {
const [{ isAuthenticated }] = useContext(OidcContext);
return isAuthenticated ? children : <Navigate to="/login" />;
}
步骤 10 — 创建应用入口点
创建 index.jsx,通过上下文提供程序启动应用。请参阅 index.jsx 模板。
import { OidcContext, useInitOidcState } from './context/oidc.context';
import { CONFIG } from './constants';
function App() {
const oidcState = useInitOidcState(CONFIG);
return (
<OidcContext.Provider value={oidcState}>
<Router />
</OidcContext.Provider>
);
}
步骤 11 — 创建 OAuth 回调页面
在 public/ 目录中创建 callback.html,用于处理 OAuth 重定向响应。请参阅 callback.html 模板。
此静态 HTML 页面会捕获 OAuth 重定向中的 code 和 state 参数,并将其传回 SPA。
步骤 12–14 — 仅限示例应用(个人资料、导航、路由器)
Agent 指令:仅当用户选择了示例应用程序模式,或明确要求个人资料页面、导航栏或完整的路由器配置时,才执行这些步骤。
请遵循 references/sample-app-guide.md 中的完整说明:
- 步骤 12 — 使用
oidcClient.user.info()创建profile.jsx、userinfo 声明表格和编辑模态框模式 - 步骤 13 — 创建 Navbar 组件、CSS 样式表和主题化的 Home 视图
- 步骤 14 — 配置
router.jsx,包含所有受保护和公开路由
脚手架脚本
如需快速设置,请使用脚手架脚本将所有模板文件复制到项目中:
chmod +x scripts/scaffold_auth.sh
./scripts/scaffold_auth.sh \
--project-dir ./my-react-app \
--journey Login
详情请参阅 scaffold_auth.sh。
常见错误
| 错误 | 修复方法 |
|---|---|
| 未配置 CORS | 确保你的 PingAM / AIC 租户允许应用的来源、方法和标头 |
缺少 openid 范围 | 始终包含 openid — 这是 OIDC 令牌交换所必需的 |
| well-known URL 错误 | 必须以 /.well-known/openid-configuration 结尾,并包含正确的 realm。用户通常只会提供 AM 基础 URL — 请询问 realm 并构建完整 URL。 |
| 使用了 AM 基础 URL 而非 well-known URL | 如果用户提供 https://tenant.forgeblocks.com/am,请询问使用哪个 realm(alpha/bravo),并构建:<baseUrl>/oauth2/<realm>/.well-known/openid-configuration |
| 未处理的回调类型 | 在 mapCallbacksToComponents 函数中,为 Journey 使用的每种回调添加一个 case |
未调用 callback.setInputValue() | 提交步骤前始终设置回调值 — SDK 会发送你设置的值 |
| 重定向 URI 不匹配 | 配置中的 redirectUri 必须与在 PingAM / AIC 中注册的 URI 完全一致 — 包括协议(http 与 https)和端口号 |
| 重定向 URI 端口与应用端口不匹配 | 如果用户指定的 redirectUri 端口为 8443,而 appPort 端口为 8444(或反之),请提醒他们 — OAuth 流程正常运行要求两者一致 |
| HTTP/HTTPS 混用 | SDK 在生产环境中要求使用 HTTPS;本地开发时,如果 AIC 中的 OAuth 客户端配置了 http://localhost 重定向 URI,则可以使用 http://localhost |
在 LoginSuccess 之前交换令牌 | 仅在 Journey 返回 LoginSuccess 步骤后调用 oidcClient.authorize.background() |
未处理 LoginFailure | 在调用 client.next() 后始终检查 LoginFailure — 重启 Journey 并显示错误 |
未设置回调就调用 client.next() | 推进到下一步前,始终填充回调值 |
在 constants.js 中导入 oidc | constants 文件只导出配置 — 不会直接导入或使用 @forgerock/oidc-client。OIDC 客户端在 oidc.context.js 中初始化。 |
未为示例应用生成 styles.css | 示例应用需要样式表来设置表单字段、按钮、布局和模态框。始终创建 client/styles.css 并在 index.jsx 中导入。 |
忘记在 public/ 中添加 callback.html | OAuth 回调页面必须是 public/ 目录中的静态 HTML 文件,而不是 React 路由。缺少此文件时,OAuth 重定向将失败并显示空白页面。 |
参考文档
- SDK 包参考 —
@forgerock/journey-client、@forgerock/oidc-client和可选附加组件的包选择指南 - OIDC 集中参考 — 完整的
@forgerock/oidc-clientAPI:授权、令牌交换、用户信息、注销、存储 - 回调实现 — 请参阅
assets/中的模板文件(例如text.jsx.template、password.jsx.template、boolean.jsx.template、webauthn.jsx.template)
相关技能
ping-orchestration-javascript-sdk— JavaScript 总入口技能(路由 Journey/DaVinci/OIDC,并在处理 Journey 流程时委派给此技能)ping-orchestration-android-sdk— 对应的 Android(Kotlin/Jetpack Compose)技能ping-orchestration-ios-sdk— 对应的 iOS(Swift/SwiftUI)技能