ibulog
いぶろぐ雑記
About Jobs Blog Tags
microCMSの拡張フィールドで2要素認証の設定を促す

こんにちは。トップ画像は神戸の五色塚古墳です。
住宅街のど真ん中に葺石の古墳が現れるのでビビります。

昨今のAIによるサイバー攻撃の勢いを鑑みると、パスワードに加えて2要素認証の設定がマストになってきそうです。
microCMSでもユーザーごとに2要素認証を設定できますが、未設定ユーザーへの通知などは運用でカバーする必要があります。

今回は拡張フィールドとマネジメントAPIを使って、コンテンツ詳細画面に2要素認証の設定を促す表示を出してみよう、という回です。

仕組み

microCMSの拡張フィールドは、iframeを介してフロント側にログインしているユーザーのメールアドレスを渡します。

公式ドキュメントのpostMessage例をそのまま拝借。

{
  id: 'some-id',  // iframe識別子
  action: 'MICROCMS_GET_DEFAULT_DATA',
  message: {
    data: 'iframeでデータを登録しています' // 拡張フィールドの実データ
  },
  user: {
    email: '[email protected]' // ログイン中のユーザーメールアドレス
  },
  context: {
    type: 'new_content', // コンテンツの新規作成時は'new_content'が、編集時には'edit_content'が入る
    endpoint: 'some-api', // コンテンツAPIのエンドポイント名
    content: {
      id: null // コンテンツの新規作成時はnullが、編集時には実際のコンテンツIDが入る
    }
  }
}

つまり、拡張フィールドのフロント側では、ログインしているユーザーのメールアドレスを識別できます。

拡張フィールドの詳しい仕組みなどは公式ドキュメントをご覧ください。
拡張フィールド|microCMSドキュメント

さらに、マネジメントAPIのメンバー一覧取得APIを利用すると、対象ユーザーが2要素認証を設定しているかどうかを取得できます。

こちらも公式ドキュメントのレスポンス例を拝借。

{
  "members": [
    {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "name": "test-member",
      "email": "[email protected]",
      "mfa": true,
      "inviting": false,
      "lastAccessedAt": "2026-01-01T00:00:00.000Z"
    },
    {
    ...
    }
  ],
  "totalCount": 120,
  "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

mfa プロパティが2要素認証の設定有無になります。

というわけで、

上記の流れで、コンテンツ詳細画面で2要素認証の設定を促すことができるわけです。

実装

コード全体はあとでリポジトリのURLを乗せますので、キモの部分だけ。
仕様をAIに渡せばフルオートで実装してくれる時代ではあるのですが…

フローはこんな感じ。

ログインユーザーの2要素認証の設定状況を確認するフロー

以下の公式SDKを使って実装しています。
GitHub - microcmsio/microcms-field-extension: Libraries for create field extension · GitHub

まずはmicroCMSから初期メッセージを受け取ります。

const cleanup = setupFieldExtension({
  origin,
  height: Math.ceil(document.body.getBoundingClientRect().height),
  width: '100%',
  onDefaultData: event => {
    const data = readInitialMessage(event, window.parent, origin);
    if (data) onInitialData(data);
  },
  onPostSuccess: () => {},
  onPostError: () => {},
});

送信元などを検証したうえで、メールアドレスを取り出し。

export function readInitialMessage(
  event: IncomingMessage,
  parentWindow: unknown,
  allowedOrigin: string,
): InitialData | null {
  if (
    event.isTrusted !== true ||
    event.source !== parentWindow ||
    event.origin !== allowedOrigin ||
    !isRecord(event.data) ||
    event.data.action !== 'MICROCMS_GET_DEFAULT_DATA'
  ) return null;

  const { id, user } = event.data;
  if (typeof id !== 'string' || !id || id.length > 256) return null;

  return {
    id,
    email: isRecord(user) && isEmail(user.email) ? user.email : null,
  };
}

取得したメールアドレスをサーバー側に渡します。

if (!context?.email) {
  render('unknown');
  return;
}
render('loading');

const response = await fetch('/api/mfa', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: context.email, refresh }),
  signal: requestController.signal,
  cache: 'no-store',
  credentials: 'omit',
  redirect: 'error',
});

サーバー側ではマネジメントAPIでユーザー一覧を取得して…

const url = new URL(
  `https://${serviceId}.microcms-management.io/api/v1/members`,
);
url.searchParams.set('limit', '100');
if (token) url.searchParams.set('token', token);

const page = await requestPage(url, signal);

メールアドレスとユーザーの2要素認証の設定状況を照合。あとは画面を出し分けるだけです。

if (!data.members.has(email)) return { status: 'unknown' };

return {
  status: data.members.get(email) ? 'enabled' : 'disabled',
  checkedAt: new Date(data.checkedAt).toISOString(),
};

コード全体が気になる方向けに、GitHubにコードを公開しておきます。
ibulog/microcms-extension-field-2fa-sample: microCMSの拡張フィールドでログインユーザーの2要素認証設定状況を表示するTypeScriptアプリ

上記のコードをどこかにデプロイし、microCMSの拡張フィールドで利用すれば、動作確認は可能です。

動作確認

ちゃんと動くか動作確認してみます。

まずは2要素認証が有効の状態で、コンテンツ詳細画面を開いてみます。

2要素認証が有効であることを示すコンテンツ詳細画面

きちんと有効になっている表示が出ました。

2要素認証を無効にして、再度開いてみると…

2要素認証の有効化を促すコンテンツ詳細画面

このように、2要素認証の有効化を促す画面が表示されました。

おわりに

今回は「ただ表示するだけ」という、ちょっと変わり種の拡張フィールドのユースケースの紹介でした。
この拡張フィールドは、フロント側からmicroCMSにデータを送信しないので、実は拡張フィールドを追加してもコンテンツAPIのレスポンスは変わりません。

なお、今回の拡張フィールドではメンバー一覧を取得しており、取り扱いには少し注意が必要です。
IP制限が可能なインフラを使うとか、そもそもインターネットに公開していない環境で動かすなど、気配りが必要かと思います。

おわり。