メインコンテンツへスキップ

ワークフローの連鎖

DID Connect を使用すると、複数の個別の認証セッションをリンクさせ、単一の初回インタラクションからユーザーのためのシームレスなマルチステッププロセスを作成できます。これは、ユーザー登録後のKYC、またはログイン後の取引確認のような複雑なシナリオに最適です。

このガイドでは、ワークフローを連鎖させるメカニズムと、それらの間でデータを渡す方法について説明します。

コアメカニズム

ワークフローを連鎖させる鍵は、onAuth ライフサイクルコールバックにあります。DID Connect セッションのステップが正常に完了すると、onAuth ハンドラはセッションを単に終了するのではなく、新しいセッションを開始し、ユーザーのウォレットに自動的にそれに進むように指示できます。

これは、onAuth 関数から2つの特定のプロパティを返すことによって実現されます。

  • nextWorkflow: 次の DID Connect セッションの完全なディープリンク URL。
  • nextToken: 次のワークフローのセッショントークン。

ウォレットが nextWorkflow を含むレスポンスを受信すると、すぐにこの URL を開き、ユーザーが新しい QR コードをスキャンする必要なく、プロセスの次のフェーズを開始します。元のセッションは、ワークフローのチェーン全体が完了または拒否されるまで、保留状態のままです。

セッション完了の仕組み

セッション A をセッション B にリンクする場合:

  1. セッション A の onAuth は、セッション B の nextWorkflownextToken を返します。
  2. セッション A は succeed としてマークされません。代わりに、セッション B に引き継がれたことを記録します。
  3. セッション B (チェーンの最終セッション) が正常に完了すると、自身を succeed としてマークします。
  4. 次に prevToken (セッション A のトークン) を探し、そのセッションも succeed としてマークし、チェーン全体が適切に閉じられるようにします。

Chaining Workflows

ワークフロー間のデータ受け渡し

多くの場合、あるステップから次のステップへコンテキストを渡す必要があります。例えば、ログインステップから後続の購入ステップへユーザーの DID を渡す場合などです。これは nextWorkflowDatapreviousWorkflowData を使用して実現されます。

  1. データの送信

    最初のセッションの onAuth ハンドラで、nextWorkflowData というオブジェクトを返します。このオブジェクトは自動的に Base64 エンコードされ、nextWorkflow URL に previousWorkflowData クエリパラメータとして追加されます。

  2. データの受信

    次のセッションはこのパラメータを自動的に解析します。デコードされたデータは、そのセッションのすべてのライフサイクルフック (onStart, onConnect, onAuth) 内の extraParams.previousWorkflowData オブジェクトで利用可能になります。

2つ以上のワークフローを連鎖させる場合 (A → B → C)、データはマージされます。セッション B が自身の nextWorkflowData を返すとき、それは A から受け取った previousWorkflowData とマージされ、結合されたオブジェクトが C に渡されます。

実装例

ユーザーがログインし、すぐにウェルカムメッセージへの署名を求められるシナリオを考えてみましょう。

ステップ 1: ログインワークフローの定義

ログインセッションの onAuth ハンドラで、メッセージに署名するための新しいセッションを生成し、それを nextWorkflow として返します。

login-handler.js

javascript
// これは簡略化された例です。実際のアプリでは、トークンを生成するための別のエンドポイントがあります。
const { WalletHandlers, WalletAuthenticator } = require('@arcblock/did-connect');
const get = require('lodash/get');

// authenticator と tokenStorage は初期化されていると仮定します
const authenticator = new WalletAuthenticator(/* ... */);
const tokenStorage = new MemoryAuthStorage();

const handlers = new WalletHandlers({ authenticator, tokenStorage });

// 最初のステップのハンドラ: ログイン
handlers.attach({
  app: server,
  action: 'login',
  claims: { profile: { description: 'Please provide your profile' } },
  onAuth: async ({ userDid, claims }) => {
    const profile = claims.find(x => x.type === 'profile');
    console.log(`${userDid} with name ${profile.fullName} logged in.`);

    // 次に、メッセージに署名するための次のワークフローを作成します
    // 実際のアプリでは、独自のトークン生成エンドポイントを呼び出します
    const { data: nextSession } = await axios.get('https://yourapp.com/api/did/sign/token');

    return {
      // 次のセッションの URL とトークン
      nextWorkflow: nextSession.url,
      nextToken: nextSession.token,
      // ユーザーの名前を次のステップに渡します
      nextWorkflowData: {
        fullName: profile.fullName,
      },
    };
  },
});

ステップ 2: 署名ワークフローの定義

このワークフローは、ログインステップからユーザーの名前を受け取り、それを使用して署名リクエストをカスタマイズします。

sign-handler.js

javascript
// 2番目のステップのハンドラ: メッセージに署名
handlers.attach({
  app: server,
  action: 'sign',
  claims: {
    signature: ({ extraParams }) => {
      // 前のワークフローからのデータにアクセス
      const fullName = get(extraParams, 'previousWorkflowData.fullName', 'user');
      return {
        type: 'mime:text/plain',
        description: `Hi ${fullName}, please sign this welcome message!`,
        data: `Welcome aboard, ${fullName}!`,
      };
    },
  },
  onAuth: async ({ userDid }) => {
    console.log(`${userDid} signed the welcome message.`);
    // これが最後のステップなので、nextWorkflow は返しません
    return { successMessage: 'Onboarding complete!' };
  },
});

この設定により、ユーザーはログイン用の単一の QR コードをスキャンして承認すると、すぐにウォレットにパーソナライズされた署名リクエストが表示されます。署名後、マルチステップのプロセス全体が完了します。

ワークフローの連鎖は、洗練されたユーザーフレンドリーなインタラクションを設計するための強力な機能です。複雑なオンボーディングフロー、多者間合意、または連続した認証済みステップを必要とするあらゆるプロセスを作成できます。

次に、より複雑なアプリケーション構造のための別の高度な機能について学びます。Delegated Connect ガイドを参照してください。