コンテンツにスキップ

埋め込み署名

<bf-signing> は、Bona Fide の署名ページをページ内のサンドボックス化された iframe にレンダリングし、ドキュメントに合わせてサイズを調整して、 署名者の操作を DOM イベントとして通知します。フレームワークに依存せず、軽量な React と Vue のラッパーも同梱されています。

  1. delivery: "embedded" を指定してエンベロープを作成します。これにより、受信者にはメールが送信されません。

  2. 署名者がページを開いたときに、サーバーでセッションを発行します。その際、allowedOrigins にサイトのオリジンを指定します。 埋め込みページは、そこに含まれていない親ページとは通信しません。

    // Your backend (never expose the API key to the browser)
    const res = await fetch(`https://api.bonafidesign.com/v1/envelopes/${envelopeId}/sessions`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ recipient: recipientId, mode: 'embedded', allowedOrigins: ['https://app.example.com'] }),
    });
    const { token } = await res.json(); // 'bfs_…', single-use, 10 minutes by default
  3. トークンを使って要素をレンダリングします。

    <script type="module" src="https://js.bonafidesign.com/v1"></script>
    <bf-signing session="bfs_…" theme="auto" min-height="480" max-height="90vh"></bf-signing>
    <script>
    const el = document.querySelector('bf-signing');
    el.addEventListener('completed', (e) => {
    // e.detail = { type: 'completed', envelope: 'env_…' }
    window.location.href = '/onboarding/next';
    });
    el.addEventListener('session_expiring', () => refreshSession());
    el.addEventListener('error', (e) => console.error(e.detail.code, e.detail.message));
    </script>
  4. サーバーで結果を確認します。 ブラウザのイベントは UI 向けのシグナルとして扱い、結果の判断には envelope.completed Webhook(または GET /v1/envelopes/{id})を使用してください。

属性(React / Vue の prop) デフォルト 説明
session bfs_… トークン。変更するとフレームが再読み込みされます
base-url(baseUrl) https://sign.bonafidesign.com/s/ デプロイメントのホスト型署名ルート
theme auto auto、light、dark のいずれか
locale 署名ページに渡されます
min-height、max-height(minHeight、maxHeight) 480、90vh ピクセルまたは vh。フレームはこの 2 つの間でドキュメントに合わせて大きくなり、それを超えると内部でスクロールします
timeout 30000 ページの読み込みを待つミリ秒数。超えるとコード load_timeout の error が発生します
frame-title Document signing iframe のアクセシブルなタイトル

要素には reload() メソッドもあります。たとえば新しいセッションを発行した後に使用します。

イベントはバブリングし、シャドウルートを越えて伝播し、ペイロードを event.detail に格納します。bf-event はすべてのイベントで発生します。

イベント detail
ready { type: 'ready' }:署名ページが読み込まれました
field_completed { type, field }:フィールドが入力されました
signed { type, recipient }:この受信者が送信しました
completed { type, envelope }:エンベロープが完了しました
declined { type, reason? }
session_expiring { type, expiresAt }:早めに新しいセッションを発行してください
error { type, code, message }。load_timeout と invalid_base_url を含みます

React の prop は onReady、onFieldCompleted、onSigned、onCompleted、onDeclined、onSessionExpiring、 onError、onEvent です。Vue はイベント名(@completed、@session_expiring など)と event を emit します。

  • トークンは iframe の URL フラグメント(#session=…)で渡されるため、サーバーや Referer ヘッダーに届くことはありません。 署名ページはトークンを読み取って URL と履歴から削除し、メモリ内のアクセストークンと交換します。Cookie は使用しません。
  • iframe はサンドボックス化されており(allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads)、referrerpolicy="strict-origin" が設定されています。
  • ページがメッセージを受け付けるのは、メッセージが要素自身の iframe から送られ、かつ base-url のオリジンから送られ、 かつ 名前空間付きの bona-fide.embed/1 メッセージとして解析できる場合だけです。それ以外はすべて無視されます。
  • 署名ページは、正確なオリジン(* は使用しません)に対してのみ、しかもそのオリジンがセッションの allowedOrigins に含まれている場合にのみメッセージを送信します。API も、許可されていないオリジンからの埋め込みセッションの呼び出しを拒否します。