# 【Next.js × Supabase】日記アプリに認証機能を追加する
【Next.js × Supabase】日記アプリに認証機能を追加する
前回の記事で、Next.jsとSupabaseを使った日記アプリのデプロイまでが完了しました。
今回は Phase 2 として、認証機能(ログイン)の実装に進みます。
現状の「誰でも投稿できてしまう状態」から、「自分だけがログインして書ける日記」にアップデートすることがゴールです。
実装のロードマップ
認証機能の実装は、以下の4ステップで進めていきます。
Supabase設定: メールアドレスでログインできるようにする。
ログイン画面作成: ユーザー登録とログインができる画面を作る。
日記画面の保護: ログインしていない人を弾くようにする。
セキュリティ設定(RLS): データベース側でも他人に見せない設定をする。
今回はまず、Step 1: Supabase側の設定 を行いました。
Step 1: Supabaseでメール認証を有効にする
Supabaseのダッシュボードで、メールアドレスとパスワードを使ったログインを許可する設定を行います。
手順
Supabaseのダッシュボードを開き、対象のプロジェクト(日記アプリ)に入ります。
左側のメニューから Authentication(鍵のマーク)をクリックします。
さらにメニュー内の Providers をクリックします。
プロバイダーリストの一番上にある Email をクリックして開きます。
Enable Email provider のスイッチを ON(緑色)にします。
右下の Save を押して保存します。
開発時のポイント:メール確認機能について
設定画面にある Confirm email(ユーザー登録時に確認メールを送る機能)は、開発中は確認の手間を省くために OFF に設定しました。
※本番運用する際はONにすることが推奨されますが、まずは動かすことを優先してOFFで進めます。
これでバックエンド(Supabase)側の受け入れ準備は整いました。
次はNext.js側で「ログイン画面」の実装に進みます。
Step 2: ログイン画面の実装とエラー対処
次はNext.js側で「ログイン画面」の実装に進みます。
app/page.tsx を大幅に書き換え、ログイン状態に応じて表示を切り替えるようにしました。
実装のポイント
supabase.auth.onAuthStateChange でログイン状態の変化を監視。
ログインしていない場合 (!user) は、メールアドレスとパスワードの入力フォームを表示。
ログインしている場合 (user がある場合) は、いつもの日記投稿画面を表示。
発生したトラブル1:PowerShellでサーバーが起動しない
実装後に npm run dev を実行しようとしたところ、PowerShellで以下のエラーが発生しました。
npm : このシステムではスクリプトの実行が無効になっているため、ファイル ... を読み込むことができません。
- CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException
原因と解決策
WindowsのPowerShellでは、セキュリティ設定(実行ポリシー)によってスクリプトの実行がブロックされることがあります。
PowerShellの設定を変更する方法もありましたが、今回は手っ取り早く 「コマンドプロンプト」 を使うことで回避しました。
VS Codeのターミナル設定から「Command Prompt」を選択して実行すると、すんなり起動しました。
発生したトラブル2:投稿時にエラーが発生する
ログインには成功したものの、日記を投稿しようとするとエラーが発生。
console.error(error);
// DB側にuser_idカラムがないためエラーになる
原因と解決策
プログラム側では「誰が書いたか(user_id)」を送信するように修正していましたが、データベース側(Supabase)の posts テーブルに user_id というカラムを作っていませんでした。
Supabaseの Table Editor から posts テーブルを開き、以下のカラムを追加して解決しました。
Name: user_id
Type: uuid
Step 3: 最後の仕上げ(セキュリティ設定)
最後に、RLS (Row Level Security) の設定を行いました。
これは「データベース側でアクセス制限をかける」機能です。これがないと、APIを知っていれば誰でも他人のデータを読み取れてしまいます。
設定内容
Supabaseの Authentication > Policies から、以下のポリシーを追加しました。
auth.uid() = user_id
意味
「今ログインしているユーザーのID (auth.uid())」と、「データの持ち主のID (user_id)」が一致する場合だけ、読み書きを許可する。
これで、「自分だけがログインして、自分だけの日記を管理できるアプリ」が完成しました!
Discussion