第六章:Supabaseを使った会員ログインと登録画面の実践
ReactのState(状態管理)とEffect(副作用)を理解したので、実際のビジネスプロジェクトで必須の機能「会員ログイン画面」を実装していきます。
従来のソフトウェア開発時代、上司からログインシステムを作るように言われたら、フロントエンドエンジニアは顔を曇らせ、バックエンドエンジニアは崩壊していました。パスワードの暗号化(Hash)、ソルト(Salt)の設定、SQLインジェクション対策、JWTトークンの発行、確認メールの送信、CookieとSessionの処理...これらすべてを一から実装するには1ヶ月かかり、しかもセキュリティホールが発生しやすくハッカーに侵入される危険性が高かったからです。
しかしVibe Codingの時代、私たちは車輪の再発明をしません。Supabase Authが提供する強力な機能に完全に依存します!
🛡️ Supabase Authとは?認証機能をサービスとして利用
Supabaseは単なるリレーショナルデータベース(PostgreSQL)ではなく、企業レベルのAuthentication(認証)システムが組み込まれています。 これは「認証機能をサービスとして提供(Auth-as-a-Service)」という概念です。
その仕組みは極めてシンプル:
- フロントエンド(React)がユーザーが入力したEmailとパスワードをSupabase APIに「投げる」
- Supabaseのサーバーが遠隔で全ての暗号化、認証、照合を処理
- Supabaseが結果を返す:「ログイン成功(トークン付き)」または「パスワード誤り」
バックエンドの暗号化ロジックを一切書く必要がなく、全てのセキュリティ対策(ブルートフォース攻撃対策含む)が組み込まれています!
🎨 実践演習:AIでログインと登録フォームを生成
ユーザーがメールアドレスとパスワードを入力できるフォームが必要です。前章で学んだuseStateを使って4つの状態を管理します:email(メールアドレス)、password(パスワード)、loading(読み込み中かどうか)、そしてerror(エラーメッセージ)。
🔥【Vibe Prompt実践呪文】 React + Supabaseプロジェクト(@supabase/supabase-js使用)を開発中です。
AuthForm.tsxコンポーネントを作成し、会員のログインと登録ページとしてください。要件:
- インターフェース設計:2つの入力欄(Email、パスワード)と2つのボタン(ログイン、登録)を含む。Tailwind CSSで質感のある、ガラスモーフィズム効果(backdrop-blur)のカードを中央配置。
- 状態管理:
useStateでemail、password、loading、errorを正確に管理。- コアロジック:
handleLoginとhandleSignUpの非同期(async/await)関数を実装。
- ログイン時:
supabase.auth.signInWithPassword({ email, password })を呼び出し- 登録時:
supabase.auth.signUp({ email, password })を呼び出し- フェイルセーフ:loadingがtrue時、両ボタンを「処理中...」に変更し、
disabled属性を追加して連打防止。- エラー処理:
error発生時、目立つ赤色のアラートボックスをフォーム上部に表示。成功時はalertまたはToastで通知。- Supabase API呼び出し部分を中心に詳細な日本語コメントを追加。
AIが生成するコードは非常に完成度が高いです。Supabase呼び出しロジックは次のようになります:
// ログインロジック例
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault(); // フォームのデフォルトリフレッシュを防止
setLoading(true);
setError(""); // クリック前に前回のエラーをクリア
// Supabaseの魔法のようなAPIを呼び出す
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
setError(error.message); // 失敗時、エラーメッセージを保存して表示
} else {
alert("おかえりなさい!ログイン成功!");
// TODO: ログイン成功後ダッシュボードページにリダイレクト
}
setLoading(false); // ボタンのロックを解除
};
このコードは商用レベルの品質を持ち、メインロジックだけでなくUX(フェイルセーフとエラー表示)も考慮されています。
📧 メール確認(Email Confirmation)の落とし穴
「登録(SignUp)」機能をテストしていると、奇妙な現象に気付くかもしれません:画面には登録成功と表示されるのに、Supabaseの管理画面ではユーザーステータスがWaiting for verificationで、実際にはログインできません!
これはSupabaseが最高レベルのセキュリティメカニズムをデフォルトで有効にしているためです:ユーザーのメールアドレスに「確認メール」を送信し、ユーザーがメール内のリンクをクリックして初めてアカウントが有効化されます。
開発テスト段階で毎回メール確認するのが面倒な場合、Supabaseの管理画面で一時的に無効化できます:
- Supabase管理画面 > 左メニューのAuthentication > Providersに移動
- Email設定を展開
- Confirm emailを見つけ、Offに切り替え
- Saveをクリックして設定保存
(⚠️ 商業警告:サイトを正式公開する際は必ずこのオプションを有効に戻してください。さもないと偽のメールアドレスで登録され、データベースが埋め尽くされる危険があります!)
⚠️ 【よくある落とし穴】Supabase Clientの読み込み忘れ
初心者がよく遭遇するエラー:TypeError: Cannot read properties of undefined (reading 'auth')
これはReactコンポーネントがsupabase変数を認識していないことを意味します。
AIが生成するコンポーネントの最上部で、Supabase Clientの初期化ファイルが正しくインポートされていることを確認してください。
���のファイルがない場合、AIにsrc/lib/supabase.tsを作成してもらえます。内容は通常以下のようになります:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient(supabaseUrl, supabaseKey)
そしてAuthForm.tsxでimport { supabase } from '@/lib/supabase'とインポートすれば正常に動作します。
💼 【ビジネス応用シナリオ】ペイウォール(Paywall)とデータ権限分離
ログイン機能を実装すると、サイトに「鍵」がかかります。この鍵は全てのオンライン収益化モデルの基礎です。
ビジネス応用1:サブスクリプション型コンテンツウォール(Paywall)の実装
/dashboard/premium-contentのようなルートを作成できます。ページ読み込み時にsupabase.auth.getUser()でログイン状態を確認し、未ログインならログインページにリダイレクト(router.push('/login'))。ログイン済みなら課金状態を確認します。これがNetflixや知識有料プラットフォームのコアロジックです。
ビジネス応用2:B2B企業向けデータ分離(Row Level Security) Supabase Authを使うと強力なRLS(Row Level Security)ポリシーを有効にできます。 例えば複数企業向けの在庫管理システム開発時、「A社の従業員がログインすると、APIが取得するデータは『必ず』A社の注文のみ」と設定可能。ハッカーがAPI経由でB社のデータを盗もうとしても、データベース層でSupabase Authがブロックします!このレベルのセキュリティ保護があれば、企業向けB2Bプロジェクトでデータの安全性を保証でき、プロジェクトの価格を30%以上上げられます。
次章では、絶対に公開してはいけない環境変数(Environment Variables)の設定と保護について、バックエンド開発の核心に迫ります。