この記事は、「Lovable単体のバイブコーディングを一旦降りて、分散構成のSaaSへ」と舵を切る試行錯誤の記録です。
フロントは Lovable(React)、バックエンドは AWS Lambda(TypeScript)、認証は Auth0。
まずは画面とAuth0をQuickstartで連携するところまでをやり切ります。
目的:同じく「外部サービス+Lovable」で開発する人が、初手の落とし穴で迷わないようにする。
背景と前提(なぜこうなったか)
- これまでは Lovable + Supabase + PostgreSQL で認証・認可・権限管理を運用。
- ただし Supabase 認証のマルチテナント対応がプロダクト要件に対して重く、**独自実装(Auth0 + 自作API)**に切り替えることに。
- 本記事はその移行フェーズの試行錯誤のうち、**Phase 1(認証基盤移行/フロントとAuth0の接続)**を扱う。
その辺の顛末はこちら↓に独り言として呟いてます。
Supabaseでは複雑なロジックを表現できない一方、Lovableはそれらを柔軟に書き換えてしまうので機能や品質の保護が難しいということです。
(大規模な業務を表現しようとした私に非がある)
そこで、今回の挑戦ではSupabaseをやめて認証もAPIもDBも切り出そうというわけです。
その中でも特にこの連載(になるのかわからないけど)では、認証認可部分について取り上げていこうというわけです。
こんな構成にしたい。なんてことはない、普通のAPIの構成です。
技術選定の理由(現時点の判断/暫定含む)
- フロント:Lovable(React)
- プロトタイプ速度が圧倒的。UI変更の反復が速く、試行錯誤の母数を稼げる。
- Reactエコシステム(Auth0のReact SDK、React Query 等)をそのまま使える。
- バックエンド:AWS Lambda(TypeScript)
- サーバーレスでスケールの心配が小さい/ユースごと課金で初期コストを抑制。
- API Gateway + Lambda Authorizer(または関数内検証)で Auth0のJWT検証がシンプル。
- TypeScriptでフロントと型共有がしやすく、DTOの不整合を減らせる。
- 認証:Auth0
- 組織・RBAC・カスタムクレームなどマルチテナントを意識した拡張点が揃う。
- SPA向けのSDK・ドキュメントが充実。最短で「動く」状態に持ち込める。
迷いメモ:DBは後続記事(Phase 2以降)で決める。Aurora Serverless v2 / RDS for PostgreSQL / DynamoDB を比較検討中。
LovableとのQ&A(起点の質問と答え)
なぜ上記のような構成にしようとしたかというと、Lovableに聞いたらそのように教えてくれたからです。
まぁLovableに聞かずともこうしたでしょうけども。。。笑
以下はLobableに聞いた内容と答えです。
Q.
/loginでの認証をAuth0に変更する。何をしたらいい?A. Auth0認証 + 独自バックエンドAPI移行の包括的なプランを提案します。
Auth0 + 独自バックエンドAPI移行プラン
Phase 1: 認証基盤移行
Auth0セットアップAuth0アカウント・アプリケーション設定
@auth0/auth0-react導入
ログイン・サインアップフローをAuth0 Universal Loginに変更
認証コンポーネント変更Login.tsx: Auth0 loginWithRedirect()に変更
AuthContainer.tsx: Auth0 useAuth0()フックに変更
Supabase認証関連フック削除
今日やること(ゴール)
- Auth0 テナント&SPAアプリを作る
- Allowed Callback / Logout / Web Origins / CORS を正しく設定
- React(Lovable)に @auth0/auth0-react を導入
-
/loginを Universal Login にリダイレクトする実装へ置き換え - ログイン後に ユーザー情報(IDトークン) が取れるのを確認
- ※ API用Access Token(audience付き) は Phase 2 で扱う
構成図(Phase 1:バックエンド未接続の最小構成)
[Browser / Lovable(React)]
│ loginWithRedirect()
▼
[Auth0 Universal Login]
│ (Code + PKCE)
▼
[Browser ← redirect_uri]
(SDKがセッション/トークン管理)
ここではまだ Lambda は呼ばない。API呼び出しは Phase 2 で追加。
手順① Auth0 テナント&アプリを用意
- Auth0 にサインアップし、テナントを作成
- Applications > Applications → Single Page Web Applications(SPA) を新規作成
-
Settings で以下を控える:
-
Domain(例:
dev-xxxxx.jp.auth0.com) - Client ID
- Application Type = Single Page Application
-
Domain(例:
-
Application URIs を設定(本番URLは
https://example.app.com/を想定):-
Allowed Callback URLs:
http://localhost:3000/,https://example.app.com/
※authorizationParams.redirect_uriと完全一致させる(末尾スラッシュも含めて揃える)。 -
Allowed Logout URLs:
http://localhost:3000/,https://example.app.com/ -
Allowed Web Origins:
http://localhost:3000,https://example.app.com※オリジンはパスなし -
Allowed Origins (CORS):
http://localhost:3000,https://example.app.com※こちらもパスなし
-
Allowed Callback URLs:
-
Advanced > OAuth:
RS256/OIDC Conformantを推奨 - Universal Login:New を使用。まずは Database Connection を1つ有効化してテストユーザーを作る
試行錯誤ログ:
redirect_uriと Allowed Callback の末尾スラッシュ不一致でエラーになりがち。ローカル/本番ともに表記を統一する。
手順② 環境変数を用意(Vite想定。CRA/Nextは読み替え)
ここで初めてViteというものを知りました。以下で勉強をさせていただいた。
しかしLovableが提示してくれたのはいいのだが、今はまだ環境変数を設定できない。
なお、設定するなら以下のようになるとのこと。
今後Lovableから抜くときに設定ファイル化し、今は画面に埋め込んでもらった。
.env:
VITE_AUTH0_DOMAIN=dev-xxxxx.jp.auth0.com
VITE_AUTH0_CLIENT_ID=xxxxxxxxxxxxxxxx
# Phase 2 でAPIを使う場合だけ有効化:
# VITE_AUTH0_AUDIENCE=https://api.example.com
VITE_AUTH0_REDIRECT_URI=http://localhost:3000
手順③ フロントに Auth0 React SDK を導入
これはLovableに以下のようにお願いして、すぐに実装が完了しました。
Q.では、まず画面にAuth0を導入して。ログアウトもよろしく。
A.
Thought for 13 seconds
Auth0の導入を開始します。まずSDKを追加して基本設定を行います。
Auth0を画面に導入しました。現在のTODOで YOUR_AUTH0_DOMAIN と YOUR_AUTH0_CLIENT_ID の設定が必要です。
一瞬!!!
動くのかはまだわからない。
そして、ボタンを押しても動かなかった。笑
トレースするとAuth0に向けてリクエストは飛んでいるので、次は設定の整合を見直してみる。
これで動けば Phase 1 のゴール達成だったが・・・(画面→Auth0→戻る→ユーザー情報取得)。
Auth0 設定パラメータのチートシート(SPA)
| 項目 | 設定例 | 目的/補足 |
|---|---|---|
| Application Type | Single Page Application | React(Lovable)向け |
| Domain | dev-xxxxx.jp.auth0.com |
SDKへ渡す |
| Client ID | ランダム文字列 | SDKへ渡す |
| Allowed Callback URLs |
http://localhost:3000, https://app.example.com
|
認証後の戻り先(複数可) |
| Allowed Logout URLs | 同上 | ログアウト後の戻り先 |
| Allowed Web Origins |
http://localhost:3000 等 |
トークン取得・セッションに必要 |
| Allowed Origins (CORS) | 同上 | XHR/Fetch 用のオリジン |
| Advanced > OAuth | RS256 / OIDC Conformant | 互換性・セキュリティ |
| Universal Login | New | UX/保守性が良い |
迷いポイント:「/callback」パスを別に用意するか?→ SDKは
redirect_uriで受けられる。明示的に用意してもOK。プロジェクトのルーティング方針に合わせる。
よくあるハマりどころ(Phase 1 版)
-
API用Access Tokenが出ない/opaqueになる
→ audience を未指定。Phase 2 で Auth0 側に API(Identifier)を定義し、authorizationParams.audienceを設定してgetAccessTokenSilently()する。 -
CORS / Web Origins エラー
→Allowed Web Origins/Allowed Origins (CORS)に正しいオリジン(ポート含む)が無い。まずはローカルと本番を明示列挙。 -
リロードでセッション消える
→ 既定はメモリキャッシュ。cacheLocation="localstorage"は便利だがXSSと要相談。とりあえずデフォルトで様子見→必要になれば切替。
(次回)Phase 2:Lambda(API) を保護して叩く
- Auth0 ダッシュボードで API(Resource Server) を作成し Identifier(= audience) を発行
- React 側
Auth0Provider.authorizationParams.audienceを設定 -
getAccessTokenSilently()で Access Token を取得し、Authorization: Bearerで API Gateway + Lambda を呼ぶ - Lambda(TypeScript)側で JWKS によるJWT検証/RBAC/カスタムクレームを処理
- データ層(Aurora Serverless v2 / RDS / DynamoDB)を評価し、**移行計画(Supabase→独自DB)**を具体化
まとめ(今日の到達点)
- 試行錯誤の第一歩として、Lovable(React)×Auth0 を Quickstart で確実に接続。
-
/loginを Universal Login に寄せ、認証リクエストが飛ぶところまで確認。 - 次回は AWS Lambda(TypeScript) の 保護API を立てて、audience付きトークンで叩く。ここからが本番の泥臭いところ。
- その前に、認証の整合をとるところが先かあ・・・・


