---
date: 2025-12-24 09:00:00
description: FileMaker OData API を外部ドメイン（SPA）から OAuth 認証で利用する際の認証フローを検証。クロスオリジンリダイレクトの成功例と、API実行時に直面するCORS制限、およびその解決策としての中間サーバーの必要性について解説します。
title: FileMaker OData API を外部ドメイン（SPA）から OAuth 認証で利用する際の認証フローの調査と検証
updatedDate: 2026-01-23 18:00:00
---

## 更新履歴

> **2026年01月23日 追記**
>
> 本記事の検証結果を元に、Angular (SPA) を使用した実装デモを作成しました。
> SPA（Angular）から FileMaker Data API を安全に使うための OAuth 認証とセキュリティ構成

### 目次

- [1. はじめに](#introduction)
- [2. OAuth プロバイダ情報の取得](#get-provider-info)
- [3. 認証用URLとリクエストIDの取得](#get-auth-url)
- [4. 認証フローと Identifier の取得](#authenticate)
- [5. OData API の実行と CORS の壁](#execute-api)
- [6. 技術的な考察と課題](#consideration)
- [7. まとめ](#conclusion)

> **この記事のポイント**
>
> - OAuth プロバイダを使用した OData API 接続の実証
> - 外部ドメイン（SPA）を経由して FileMaker Server へ認証情報を引き渡すリダイレクトフロー
> - 外部ドメイン（SPA）へのリダイレクトバックが成功することを確認
> - ブラウザからの直接アクセス時に発生する CORS エラーと対策

## 1. はじめに

Angular、React、Vue.js などのモダンなフロントエンドフレームワーク（SPA）と FileMaker を組み合わせたい場合、FileMaker OData API は有力な選択肢です。特にセキュリティ要件の高い環境では「OAuth アイデンティティプロバイダ（IdP）を利用した認証」が必須となるケースがあります。

本記事では、外部ドメインで運用される SPA からの接続を想定し、検証用ドメイン `https://redirect.frudens.com/` を使用して、認証から API 実行までのフローを検証します。


> **OAuth アイデンティティプロバイダを使用したデータベースセッションへのログイン**
>
>
> OAuth アイデンティティプロバイダを使用して共有データベースにログインするには、データベースを参照する API エンドポイントを使用します。
>
>
> ヘッダの X-FM-Data-OAuth-Request-Id 文字列および X-FM-Data-OAuth-Identifier 文字列を使用して共有データベースへのアクセスを認証します。
>
>
> 認証されると、API エンドポイントから対応する応答を受け取ります。


    [OAuth アイデンティティプロバイダを使用したデータベースセッションへのログイン](https://help.claris.com/ja/odata-guide/content/log-in-database-session-oauth-odata.html)


公式ドキュメントを読み解きながら、実際に接続できるか検証を行います。

### 認証フローの全体像

検証の結果判明した、正常な認証フローをシーケンス図に整理しました。SPA が Google からのコールバックを一度受け取り、即座に FileMaker Server（FMS）へ転送する流れになります。



        sequenceDiagram
        autonumber
        actor User as ユーザー（ブラウザ）
        participant SPA as SPA
（redirect.frudens.com）
        participant FMS as FileMaker Server
（demo-ig5aiy.frudens.com）
        participant Google as OAuthプロバイダ
（Google）

        note over SPA, FMS: Step 1 & 2 プロバイダ情報・認証URL取得
        SPA->>FMS: GET /oauth/getoauthurl（Return-URL指定）
        FMS-->>SPA: 認証用URL + X-FMS-Request-ID

        note over User, Google: Step 3 認証プロセス
        SPA->>User: 認証用URLへリダイレクト
        User->>Google: Googleログイン & 許可
        Google-->>User: リダイレクト（認証コード）
        note right of User: Google -> SPA（/oauth/redirect）

        note over SPA, FMS: Step 4 FMSへの転送とIdentifier発行
        User->>FMS: リダイレクト（認証コード + state）
        note right of User: SPA -> FMS （/oauth/redirect）
        note right of FMS: FMS内部でセッション生成
Identifier 発行
        FMS-->>User: 最終リダイレクト（Identifier付与）
        note right of User: FMS -> SPA（/my/callback）

        note over SPA, FMS: Step 5 OData API 実行
        User->>SPA: SPA画面表示（パラメータ取得）
        SPA->>FMS: GET /fmi/odata/v4/...
        note right of SPA: 【課題】ブラウザから直接叩くと
CORSエラーになる

  SPA を経由する認証プロセスのシーケンス図

## 2. OAuth プロバイダ情報の取得

まず、FileMaker Server で有効になっている OAuth プロバイダの情報を取得します。今回は事前に Google をプロバイダとして登録済みである環境を前提とします。


```shell
#!/bin/bash

HOST="demo-ig5aiy.frudens.com"
OUTPUT="response_provider_info.json"

curl -X GET "https://${HOST}/fmws/oauthproviderinfo" | tee "${OUTPUT}"
```

  get_oauth_provider_info.sh

レスポンスとして、プロバイダ設定（Google）の情報が返ってきます。ここで `ProviderID` や `AuthType` などのパラメータを確認します。


```json
{
  "data": {
    "Provider": [
      {
        "AdditionalQueryParams": "",
        "AuthCodeEndpoint": "accounts.google.com/o/oauth2/auth",
        "AuthType": 2,
        "ClientID": "368922767362-no0be7vevtdopfh5mm51p5cnsvo51sk5.apps.googleusercontent.com",
        "Icon": "http://filemaker.parseapp.com/google.png",
        "Name": "Google",
        "OIDCEnabled": true,
        "ProviderEnabled": true,
        "ProviderID": 3,
        "Response Type": "code",
        "Scope": "profile openid email"
      }
    ]
  },
  "result": 0
}
```

  response_provider_info.json

## 3. 認証用URLとリクエストIDの取得

次に、実際の認証プロセスを開始するためのURLを生成します。ここで重要なのは、`X-FMS-Return-URL` に **FileMaker Server とは異なる外部ドメイン（SPA の URL）** を指定している点と、レスポンスヘッダに含まれる `x-fms-request-id` です。これが後のAPIリクエスト時のキーとなります。


```shell
#!/bin/bash

HOST="demo-ig5aiy.frudens.com"
REDIRECT_HOST="redirect.frudens.com" # SPAのドメイン
TRACKING_ID="123"
PROVIDER="Google"
HEADER_FILE="response_auth_headers.txt"
BODY_FILE="response_auth_url.txt"

# Return-URL に外部ドメインを指定
curl -X GET "https://${HOST}/oauth/getoauthurl?trackingID=${TRACKING_ID}&provider=${PROVIDER}&address=${REDIRECT_HOST}&X-FMS-OAuth-AuthType=2" \
  --dump-header "${HEADER_FILE}" \
  --header "X-FMS-Application-Type: 9" \
  --header "X-FMS-Application-Version: 15" \
  --header "X-FMS-Return-URL: https://${REDIRECT_HOST}/my/callback" | tee "${BODY_FILE}"
```

  get_auth_url.sh

実行すると、Google の認証画面へ遷移するための長い URL が取得されます。


```text
https://accounts.google.com/o/oauth2/auth?client_id=368922767362-no0be7vevtdopfh5mm51p5cnsvo51sk5.apps.googleusercontent.com&redirect_uri=https://redirect.frudens.com/oauth/redirect&scope=profile openid email&response_type=code&state=WC1GTVMtUmVxdWVzdC1JRD0xMTRERDk5RTA3NzcyQjBCQjRBQjM0QUI5MkYwRUIwOA==.WC1GTVMtT0FVVEgtUHJvdmlkZXI9R29vZ2xl.WC1GTVMtT0F1dGgtQXV0aFR5cGU9Mg==.WC1GTVMtUmVkaXJlY3QtVVJMPWh0dHBzOi8vcmVkaXJlY3QuZnJ1ZGVucy5jb20vb2F1dGgvcmVkaXJlY3Q=.
```

  response_auth_url.txt

同時に出力されたヘッダファイルを確認し、`x-fms-request-id` を控えます。


```text
HTTP/2 200
server: nginx
date: Wed, 24 Dec 2025 00:08:26 GMT
content-type: text/html; charset=utf-8
content-length: 458
accept-ranges: bytes
x-fms-request-id: 114DD99E07772B0BB4AB34AB92F0EB08
x-fms-result: 0
strict-transport-security: max-age=31536000; includeSubDomains
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
access-control-allow-origin: ubuntu-gk9
access-control-allow-credentials: True
access-control-allow-headers: Content-Type,Authorization
```

  response_auth_headers.txt

この `114DD99E07772B0BB4AB34AB92F0EB08` が、後の API 実行時にヘッダへ付与する **X-FM-Data-OAuth-Request-Id** となります。

### 補足 state パラメータの構造

取得された認証用 URL に含まれる `state` パラメータを解析すると、「ドット（`.`）」で区切られた複数の Base64 文字列で構成されており、デコードすると FileMaker Server が内部で管理するセッション情報が埋め込まれていることが分かります。


| # | Base64文字列 | デコードされた値 |
| --- | --- | --- |
| 1 | WC1GTVMtUmVxdWVzdC1JRD0xMTRERDk5RTA3NzcyQjBCQjRBQjM0QUI5MkYwRUIwOA== | X-FMS-Request-ID=114DD99E07772B0BB4AB34AB92F0EB08 |
| 2 | WC1GTVMtT0FVVEgtUHJvdmlkZXI9R29vZ2xl | X-FMS-OAUTH-Provider=Google |
| 3 | WC1GTVMtT0F1dGgtQXV0aFR5cGU9Mg== | X-FMS-OAuth-AuthType=2 |
| 4 | WC1GTVMtUmVkaXJlY3QtVVJMPWh0dHBzOi8vcmVkaXJlY3QuZnJ1ZGVucy5jb20vb2F1dGgvcmVkaXJlY3Q= | X-FMS-Redirect-URL=https://redirect.frudens.com/oauth/redirect |

ヘッダで取得した `x-fms-request-id` が `state` 内にも格納され、認証フロー全体を通して引き継がれている様子が見て取れます。

## 4. 認証フローと Identifier の取得

取得した認証 URL にブラウザでアクセスし、Google アカウントでログインします。

![Google アカウントのログイン画面](oauth-google-login-consent.png)

*認証用URLへアクセスした際の Google ログイン画面*

### リダイレクトの挙動

認証成功後のリダイレクトチェーンは以下のようになります。

> **認証とリダイレクトの流れ**
>
> Google -> SPA
> Google での認証後、SPA（/oauth/redirect）へ戻ります。
> SPA -> FMS
> SPA は受け取った認証コードを持って、FileMaker Server（/oauth/redirect）へリダイレクト（転送）します。
> トークン発行とIdentifier生成
> FMS 内部で認証コードからトークンとセッション（Identifier）を生成します。
> FMS -> SPA（最終リダイレクト）
> Step 3 で指定した X-FMS-Return-URL（https://redirect.frudens.com/my/callback）へリダイレクトされます。
> パラメータの受け取り
> リダイレクト時の URL パラメータに identifier が付与されます。

#### Step 4-1. Google から SPA へ

Google でのログイン完了後、SPA（`/oauth/redirect`）にリダイレクトされます。この際、URL パラメータに `code` や `state` が含まれています。


```text
https://redirect.frudens.com/oauth/redirect?state=WC1GTVMtUmVxdWVzdC1JRD0xMTRERDk5RTA3NzcyQjBCQjRBQjM0QUI5MkYwRUIwOA%3D%3D.WC1GTVMtT0FVVEgtUHJvdmlkZXI9R29vZ2xl.WC1GTVMtT0F1dGgtQXV0aFR5cGU9Mg%3D%3D.WC1GTVMtUmVkaXJlY3QtVVJMPWh0dHBzOi8vcmVkaXJlY3QuZnJ1ZGVucy5jb20vb2F1dGgvcmVkaXJlY3Q%3D.&code=4%2F0ATX87lNcMAJUdf4JjaNsrfABBUWf3xRCnhXttQjHfEBWPl5mmL-xsQ1XsT04H39j851PCg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&hd=frudens.com&prompt=consent
```

  SPAリダイレクト後のURL例

![認証後にリダイレクトされた SPA の画面。長い state パラメータが付与されている。](spa-redirect-url-parameters.png)

*認証後にリダイレクトされた SPA の画面*

#### Step 4-2. SPA から FMS へ

SPA は、このルート（`/oauth/redirect`）がロードされた際に、パラメータをそのまま引き継いで FileMaker Server（`/oauth/redirect`）へリダイレクト（転送）する必要があります。

以下は、SPA 側で実行するリダイレクト処理のイメージです（実際には現在のURLパラメータを動的に取得して構築します）。


```javascript
function redirect() {
  // const spaUrl = 'https://redirect.frudens.com/oauth/redirect?state=WC1GTVMtUmVxdWVzdC1JRD0xMTRERDk5RTA3NzcyQjBCQjRBQjM0QUI5MkYwRUIwOA%3D%3D.WC1GTVMtT0FVVEgtUHJvdmlkZXI9R29vZ2xl.WC1GTVMtT0F1dGgtQXV0aFR5cGU9Mg%3D%3D.WC1GTVMtUmVkaXJlY3QtVVJMPWh0dHBzOi8vcmVkaXJlY3QuZnJ1ZGVucy5jb20vb2F1dGgvcmVkaXJlY3Q%3D.&code=4%2F0ATX87lNcMAJUdf4JjaNsrfABBUWf3xRCnhXttQjHfEBWPl5mmL-xsQ1XsT04H39j851PCg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&hd=frudens.com&prompt=consent';
  // const fmsRedirectUrl = 'https://demo-ig5aiy.frudens.com/oauth/redirect?state=WC1GTVMtUmVxdWVzdC1JRD0xMTRERDk5RTA3NzcyQjBCQjRBQjM0QUI5MkYwRUIwOA%3D%3D.WC1GTVMtT0FVVEgtUHJvdmlkZXI9R29vZ2xl.WC1GTVMtT0F1dGgtQXV0aFR5cGU9Mg%3D%3D.WC1GTVMtUmVkaXJlY3QtVVJMPWh0dHBzOi8vcmVkaXJlY3QuZnJ1ZGVucy5jb20vb2F1dGgvcmVkaXJlY3Q%3D.&code=4%2F0ATX87lNcMAJUdf4JjaNsrfABBUWf3xRCnhXttQjHfEBWPl5mmL-xsQ1XsT04H39j851PCg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&hd=frudens.com&prompt=consent';

  // 実際には window.location.search からパラメータを取得します
  const params = new URLSearchParams(window.location.search);
  const state = params.get('state');
  const code = params.get('code');
  // ...その他のパラメータ処理

  // FileMaker Server のリダイレクト用エンドポイントを構築
  const fmsRedirectUrl = `https://demo-ig5aiy.frudens.com/oauth/redirect?state=${state}&code=${code}&...`;

  // FMS へリダイレクト
  window.location.href = fmsRedirectUrl;
}
```

  SPA 内でのリダイレクト処理イメージ

#### Step 4-3. FileMaker Server での処理とコールバック

SPA からリダイレクトされると、FileMaker Server は認証コードを検証し、トークン発行と Identifier 生成を行います。

![ネットワークタブでのリダイレクトフロー（FMSへのリクエスト）](fms-oauth-network-waterfall-1.png)

*SPA から FMS へリダイレクトされ、処理が行われている様子*

#### Step 4-4. FMS から SPA へ

処理が完了すると、FMS は最初に指定した `Return-URL`（SPA の `/my/callback`）へリダイレクトします。この際、URL パラメータに重要な **identifier** が付与されます。

![ネットワークタブでのリダイレクトフロー（SPAへのコールバック）](fms-oauth-network-waterfall-2.png)

*FMS から SPA へ戻ってきた際のリクエスト。Identifier が付与されている。*

この `identifier` の値（`3E563425F1AE77B11636F59CB344D64C`）が、API ヘッダの **X-FM-Data-OAuth-Identifier** になります。

これで OData API へのリクエストに必要な「2つの鍵」が揃いました。

- **X-FM-Data-OAuth-Request-Id**（Step 3でヘッダから取得）
- **X-FM-Data-OAuth-Identifier**（Step 4でURLから取得）

## 5. OData API の実行と CORS の壁

公式ドキュメントに従い、取得した2つのキーを使用して、テーブル一覧を取得するリクエストを送信してみます。


> **データベース内のテーブルおよびテーブルオカレンスの一覧の取得**
>
>
> データベースからテーブルの一覧を取得するには、HTTP GET メソッドを使用して URL にデータベース名を追加します。


    [テーブルの一覧の取得 | Claris FileMaker OData API ガイド](https://help.claris.com/ja/odata-guide/content/get-list-of-tables.html)


以下のスクリプトで実行します。


```shell
#!/bin/bash

HOST="demo-ig5aiy.frudens.com"
OUTPUT="response_table_list.json"
DATABASE_NAME="blank01"

# 取得した値をセット
REQUEST_ID="114DD99E07772B0BB4AB34AB92F0EB08"
IDENTIFIER="3E563425F1AE77B11636F59CB344D64C"

curl -X GET "https://${HOST}/fmi/odata/v4/${DATABASE_NAME}" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --header "X-FM-Data-OAuth-Request-Id: ${REQUEST_ID}" \
  --header "X-FM-Data-OAuth-Identifier: ${IDENTIFIER}" | tee "${OUTPUT}"
```

  get_table_list.sh

シェルスクリプト（サーバーサイド）からの実行では、正常にデータが取得できました。


```json
{
  "@context": "https://demo-ig5aiy.frudens.com/fmi/odata/v4/blank01/$metadata",
  "value": [
    {
      "name": "tableA",
      "kind": "EntitySet",
      "url": "https://demo-ig5aiy.frudens.com/fmi/odata/v4/blank01/tableA"
    },
    {
      "name": "tableB",
      "kind": "EntitySet",
      "url": "https://demo-ig5aiy.frudens.com/fmi/odata/v4/blank01/tableB"
    }
  ]
}
```

  response_table_list.json

### ブラウザからの実行と CORS エラー

ここが重要なポイントです。認証フロー自体はリダイレクト（ブラウザのページ遷移）で行われるため成功しますが、その後のデータ取得（Fetch API や Axios）は非同期通信で行われます。

FileMaker OData API は **CORS（Cross-Origin Resource Sharing）** に対応していないため、ブラウザ（JavaScript）から直接 OData API を叩くと、ブラウザのセキュリティ機能（同一生成元ポリシー）によりブロックされます。

![ブラウザのコンソールでCORSエラーを確認](browser-console-cors-error.png)

*ブラウザからの直接アクセスによる CORS エラー*

つまり、SPA からデータにアクセスするためには、API リクエストを中継する**中間サーバー（BFF: Backend For Frontend）** またはプロキシが必要不可欠となります。

## 6. 技術的な考察と課題

検証の結果、仕組みの解明とともに、運用上の注意点も判明しました。

### セッションの有効期限とセキュリティ

今回取得した `X-FM-Data-OAuth-Identifier` は、Google のアクセストークンそのものではなく、FileMaker Server が生成した独自のセッション ID であると推測されます。

FileMaker Server Admin Console の **[構成] > [FileMaker クライアント]** 設定にある **[セッションタイムアウト]** がこの Identifier の有効期限に影響するか検証しました。

![FileMaker Server Admin Consoleのセッションタイムアウト設定画面](fms-admin-console-session-timeout.png)

*検証時の FileMaker Server 設定（セッションタイムアウトを10分に設定）*

検証の結果、タイムアウトを10分に設定してもセッションは切断されず、**6時間以上経過しても Identifier は有効なまま** でした。

このことから、OData API の OAuth セッション（Identifier）は、Admin Console の標準的なクライアントタイムアウト設定の影響を受けない（あるいは非常に長い有効期限が固定されている）可能性が高いです。

FileMaker OData API は標準規格（OData Standard）に準拠していますが、明示的なログアウトのエンドポイントが見当たりません。もし Identifier が実質的に無期限、あるいは長時間有効である場合、フロントエンドでこの値を保持し続けることはセキュリティリスクとなります。

この点からも、BFF レイヤーを設け、Identifier の管理をサーバーサイドで行う構成が望ましいと考えられます。

後日、Claris に連絡して内部仕様について確認を行う予定です。

## 7. まとめ

今回の検証により、独自の認証ロジックが必要なデメリットはありますが、SPA などのモダンなフレームワークのバックエンドとして FileMaker OData API を利用する道筋が見えました。

> **検証の結論**
>
> - リダイレクト連携の確立
> X-FMS-Return-URL を活用することで、外部 SPA と FileMaker Server 間での認証情報の受け渡しが可能です。
> - BFF（中間サーバー）の必要性
> ブラウザの CORS 制限を回避し、Identifier を隠蔽・管理するために、API リクエストを中継するサーバーが必須となります。
> - セキュリティリスクへの対応
> Identifier の有効期限が長いため、フロントエンドに直接露出させず、サーバーサイドで厳重に管理する設計が求められます。

「SPA から直接接続する」という完全なサーバーレス構成は難しいものの、適切なアーキテクチャを採用することで、FileMaker のデータを活用した高機能な Web アプリケーションは十分実現可能です。

### FileMaker と Web の連携でお困りですか？

本記事のような API 連携やシステム構築について、技術的なサポートを行っております。「実現したいことはあるが、技術的なハードルが高い」とお悩みの方は、ぜひ無料相談からお気軽にご連絡ください。

- FileMaker と Web アプリケーションをセキュアに連携させたい
- EC サイト運用や業務フローの自動化（スクレイピング等）を検討している
- 既存の FileMaker 資産を活かして、モダンな Web サービスを構築したい