← health-moniter 目次へサイトトップ

HM-002

health-moniter Cloudflare移行とAccess保護

作成: 2026-06-27 / 対象: Cloudflare Workers・D1・Access への移行記録

要約。 ローカルの Python / FastAPI / SQLite 構成を TypeScript / Hono / Cloudflare Workers / D1 へ移し、health.lunelukkio.comだけを入口にしてCloudflare AccessのGoogle認証で本人限定にしました。移行中の「D1 binding変更後の空DB」と「Access callbackが無効なworkers.devへ戻る」問題は、どちらも設定上の識別子と実体の対応ずれが原因でした。
用語規約。「ローカルD1」はMiniflareが管理する開発用SQLite、「本番D1」はCloudflare上のD1です。「Access」はアプリ内ログインではなく、Workerの手前で通信を止めるCloudflare Zero Trustの認証層です。

1. ローカル版からCloudflare版へ

処理の目的は変えず、常時起動サーバーとローカルファイルへの依存をCloudflareの実行環境へ置き換えました。Dashboardで行ったCloudflare設定の再現手順はHM-003、旧構成はHM-001: ローカル版の構成を参照してください。

ローカル版からCloudflare版への移行 Before: ローカル React / Vite PythonFastAPI SQLite 移行 After: Cloudflare React TypeScriptHono / Worker Cloudflare D1 症状記録 → 気象同期 → 相関解析 → 可視化・出力、という目的は同じ
図1. 実行場所と永続化層を置き換え、同じドメイン処理をエッジへ移した。
領域Cloudflare版確認
API・保存TypeScript + Hono + D1、症状・地点CRUD実装済み
気象Open-Meteo Geocoding / Historical / Forecast同期実装済み
日時UTCで保存し、地点タイムゾーンで日次集計UI変換も対応
解析・出力Pearson、Spearman、p値、CSV実装済み
検証実D1を使うWorkers Vitest11件成功、build / lint成功

2. 記録から分析結果まで

Accessを通過したリクエストだけがWorkerへ届きます。WorkerはD1を正本とし、必要な気象だけをOpen-Meteoから補完します。

認証からUIとCSVまでのデータフロー ブラウザCloudflareAccess Worker / HonoAPI・集計・相関 D1Open-MeteoReact UIグラフ / CSV UTCで保存地点タイムゾーンで日次集計 → 解析・表示
図2. 認証、保存、気象補完、集計、表示を一方向の流れとして整理した。

3. D1 binding変更で空DBに見えた理由

MiniflareのローカルD1ファイルはD1の識別子に対応して作られます。初期migrationを誤った識別子で適用した後に正しいbindingへ差し替えたため、旧SQLiteにスキーマが残り、現bindingが参照する新SQLiteは空でした。データ削除ではなく参照先の分離です。

D1 binding変更によるローカルSQLiteの分離 誤ったdatabase_idmigration適用 旧ローカルSQLiteスキーマあり・孤立 正しい現bindingdatabase_id差替え後 新ローカルSQLite当初は空 修正現bindingへmigration再適用8テーブル + 3インデックス 同じ実体ではない
図3. database_id変更でローカルDBの対応先が変わる。現bindingへのmigration再適用で修正した。

4. Custom DomainとAccess callback

当初はAccessのdestinationにcustom domainとworkers.devの両方を登録していました。一方Worker側ではworkers.devを無効化済みだったため、認証後callbackがworkers.devへ戻ると「There is nothing here yet」になりました。destinationをcustom domainだけに揃えて解消しました。

Access callback誤設定と修正後の経路 修正前Google認証 Access custom domain workers.dev無効化済み callback失敗 修正後 ブラウザAccessGoogle / Only mehealth.lunelukkio.comWorker / D1 workers_dev=false / preview_urls=false / destinationはcustom domainのみ
図4. 認証の入口とWorkerの公開経路を一つに揃え、callback先の不整合を除いた。

5. 現在のセキュリティ境界

確認項目結果意味
認証Googleのみ、本人限定、24時間未認証通信はWorkerの前で停止
公開経路custom domainのみworkers.devとpreview URLは無効
本番D18テーブルすべて0件調査時点で不審な書込みなし
デプロイ履歴既知の所有者のみ未知のデプロイなし
侵入兆候確認されず将来の安全を保証するものではない
Worker側JWT二重検証の判断。 custom domain以外を無効化し、利用者も一人なので、Accessに加えてアプリでもJWTを検証する二重化は現状必須ではありません。経路追加、複数ユーザー化、APIの別用途利用時に再検討します。

通常のWebアクセスだけで第三者がWorkerのプログラムを書き換えることはできません。注意すべき入口はCloudflare/GitHubアカウントの侵害、デプロイトークン流出、依存パッケージの供給網、将来追加する入力処理のXSSです。

6. A1〜A5の進行

段階実施内容検証
A1ローカル版の機能とデータ構造を把握既存フローを基準化
A2D1作成、binding修正、migration適用8テーブル・3インデックス
A3Hono / D1 API、気象同期、解析、CSV、React連携Vitest 11件、build、lint
A4custom domainへデプロイ旧workers.devが404
A5Google IdPとAccess本人限定設定未認証302、認証後表示

参考資料

構成・テスト結果・調査結果は2026-06-27時点のプロジェクト作業記録に基づく。外部サービスの仕様は公式資料を参照。

← health-moniter 目次へ更新履歴