不動産相場チェッカーの Colab 版(Googleが提供するプログラム実行環境で動くバージョン)は完成して公開済みだけど、使うには Google アカウントでログインして Colab を開く必要があった。「もっと手軽に、ブラウザだけで使えないか?」という要望が出ていた。
ただし、国交省の不動産データを取得するための API(プログラム同士が会話する窓口)には2つの制約がある:
放置すると、せっかく作った相場分析ツールが「Colabを使える人限定」のままで、スマホやタブレットから気軽に使えない。
「静的HTML 1ファイル」+「Cloudflare Workers(クラウドフレアが提供する、世界中に分散した小さなサーバー)で中継サーバー」という構成で実装・デプロイが完了した。
ユーザーのブラウザからの通信ルート
国土地理院のAPIはCORS(異なるサイト間の通信許可)に対応しているので直接呼び出せるが、国交省のAPIは対応していないので中継サーバーを経由する。この中継サーバーがCloudflare Workersの役割。
ユーザーが入力したAPIキーは、ブラウザの localStorage(ブラウザ内にデータを保存する機能。ページを閉じても消えない)に保存される。サーバーには一切保存しない。中継サーバーはキーを「通過させるだけ」で、記録も保管もしない。
| 対策 | 具体的な方法 |
|---|---|
| XSS防止(悪意のあるスクリプトの埋め込み防止) | textContent(テキストとして安全に表示する方法)のみ使用。innerHTML(HTMLを直接書き込む方法。攻撃に悪用されやすい)は禁止 |
| CSP(通信先の制限) | 中継サーバーと国土地理院APIだけに通信を許可。他のサイトへの通信をブロックする |
| 外部スクリプト不使用 | 外部の読み込みなし。攻撃経路を最小化する |
| APIキー保護 | ブラウザ内のみ保存。URLパラメータには含めない。「キーを削除」ボタンで即消去可能 |
docs/app.html(Webアプリ本体)— 分析ロジック・UI・CSSすべてを含む1ファイル。GitHub Pagesで配信するdocs/index.html(既存LP)— 「Web版を使う」ボタンを追加するだけの軽微な変更workers/src/index.ts(中継サーバー本体)— Honoフレームワークで構築。国交省APIへのリクエスト中継とCORS対応を担当workers/wrangler.toml(中継サーバーの設定ファイル)— デプロイ先の設定を記述workers/package.json(依存パッケージ一覧)— HonoとWrangler(開発ツール)の定義workers/tsconfig.json(TypeScript設定)— 型チェックの設定なぜCloudflare Workersなのか? — APIキーはリクエストヘッダー(通信の付帯情報)に含まれて中継サーバーを通過するが、Cloudflare Workersは X-API-Key などのヘッダーを自動的にログから隠す機能がある。つまりキーが中継サーバーのログに残るリスクが低い。無料枠で1日10万リクエストまで使えるのでコストもかからない。
暗号化しないの? — ブラウザ内でAPIキーを暗号化する方法もあるが、暗号化する鍵もブラウザ内に置くことになるので実質無意味(金庫と鍵を同じ場所に置くようなもの)。それよりもXSS(悪意のあるスクリプト埋め込み)を防ぐことに注力する方が効果的。
なぜHonoなのか? — 最初は「外部ライブラリなしでJavaScript 1ファイル」を検討したが、Cloudflare Workers の公式推奨フレームワークであり、CORS ミドルウェアなど必要な機能が組み込みで用意されている。わずか14KBと超軽量なのでYAGNI/KISSにも反しない。
なぜReactを使わないのか? — 入力フォーム1個とテーブル2個だけの画面にReactは過剰。バニラ(素の)HTML/CSS/JavaScriptで十分に実現でき、ビルド環境も不要。YAGNI(今必要ないなら作らない)とKISS(シンプルに)の原則に従った判断。
見送ったこと — 認証機能やユーザーアカウント機能は作らない。「APIキーを自分で管理する」というシンプルな方式を維持することで、ユーザーデータを預からない=漏洩リスクゼロの設計にしている。
残りのタスク — Colab版と同じ住所で分析して坪単価が一致するかの突き合わせ検証がまだ。GitHub Pagesへのデプロイ完了後にブラウザで実際に動作確認する予定。