Headless Identityフローの最終段階は、APIで取得したアクセストークンをブラウザのUIセッション(Cookie)に変換し、マイページへ遷移させることです。
最終となる第五弾の本記事では、公式推奨エンドポイントの利用と、実装時に直面する細かな仕様の差異を解説します。
前回の記事はこちら
【ペットクリニックサイト 制作日誌 Vol.4】ReactとSalesforce Headless API連携:CORS制約とレートリミット対策
今回の連載記事で作成したReactサイトとSalesforceコンポーネントをGitHubで公開しています。 ぜひ Clone して、あなたの組織で動かしてみてください。

事実(仕様に基づくセッション化)
- 認証コードフローを利用する場合、PKCE(
code_challengeとcode_verifier)の実装が必須です。 - アクセストークンからログインCookie(セッション)を生成するためには、手動による
frontdoor.jspのURL組み立てではなく、Single-Access UI Bridge API (/services/oauth2/singleaccess) の使用が公式で推奨されています。
実装コード(UI Bridge APIによるリダイレクト)
// salesforceAuth.ts
export async function redirectToLwrMypage(accessToken: string): Promise<void> {
const urlObj = new URL(LWR_MYPAGE_URL);
const basePath = urlObj.pathname.split('/mypage')[0];
const singleAccessEndpoint = `${API_BASE_URL}${basePath}/services/oauth2/singleaccess`;
// UI Bridge APIへトークンを送信し、遷移用URLを取得します
const response = await fetch(singleAccessEndpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
// 仕様の揺れに対応するため、redirect_uriとretURLの両方を付与して安定させます
body: `redirect_uri=${encodeURIComponent(urlObj.pathname)}&retURL=${encodeURIComponent(urlObj.pathname)}`
});
const data = await response.json();
// Reactのプリフェッチを避けるため、window.location.replaceで直接遷移を実行します
window.location.replace(data.frontdoor_uri);
}
推測・見解(設計判断とトレードオフ)
Single-Access APIの採用理由
手動で frontdoor.jsp?sid=<トークン> を組み立てるアプローチは実装が容易ですが、Salesforceのセキュリティアップデートにより非推奨化・制限されるリスクが高まっています。
アーキテクチャの堅牢性を担保するため、正規のAPIを経由してワンタイムの遷移URL(frontdoor_uri)を発行させる手法を選択すべきです。このAPIを経由して確立されたセッションは、通常のログインと同様にプロファイル設定の期間(デフォルト2時間等)維持されます。
retURL と redirect_uri の両方指定
公式ドキュメントやSalesforceのバージョン(コミュニティ環境かコア環境か)によって、着地先の指定パラメータが揺れることがあります。確実に指定したマイページへ着地させるためのハックとして、リクエストボディに両方のパラメータを含めておくのが安全です。
リダイレクトの連鎖
ユーザーの目には「Reactから直接マイページに飛んだ」ように見えますが、裏側では一瞬だけ frontdoor.jsp を経由して 302 Redirect が発生しています。このタイミングでCookieが焼かれるため、SafariのITP(トラッキング防止機能)などのサードパーティCookie制限の影響を受けないよう、必ず「同一ドメイン(カスタムドメイン等)」で動かすインフラ構成が必須になる点も重要です。
開発時の知見(ハマりどころ)
- PKCE(code_verifier)のパースエラー
JSで標準的な128文字のランダム文字列(記号含む)を生成して/authorizeへ渡すとinvalid code verifierで拒否される現象が確認されています。Salesforce側のパーサー挙動に対応するため、「記号なしの英数字のみで、長さを64文字にする」ことでエラーを回避できます。 - ワンタイムURIのプリフェッチ消費
singleaccessAPIが返却するfrontdoor_uriは1回限りの使い捨てです。React等のフレームワークでは、画面内のリンクをバックグラウンドでプリフェッチする機能がデフォルトで有効な場合があり、システムが勝手にURIを叩いてトークンを消費してしまうことがあります。ユーザーがリンクを踏んだ際に「セッションが無効です」となる事態を防ぐため、プリフェッチの無効化またはJSからの明示的なwindow.location.replaceによる遷移が必須です。
まとめ
APIで取得したアクセストークンをExperience CloudのUIセッション(Cookie)へ変換するプロセスは、Headless認証フローの最難関です。
セキュリティリスクを伴うURLクエリでのトークン引き渡しを避け、公式推奨のSingle-Access UI Bridge APIを利用してワンタイムのfrontdoor_uriを発行する設計が不可欠です。
同時に、PKCEの厳格な文字列仕様や、モダンフロントエンドのリンクプリフェッチ機能によるワンタイムトークンの意図せぬ消費を防ぎ、堅牢でシームレスなマイページ連携を実現してください。
参考URL
Headless Identity APIs: Headless Registration Flow for Public Clients
Configure Experience Cloud Settings for Headless Passwordless Login
Proof Key for Code Exchange (PKCE) Extension
Generate a Frontdoor URL to Bridge into UI Sessions


読者の声