【🔰初心者向け】SNS型webアプリを作成しよう 第3回_Supabaseをセットアップして、投稿をデータベースに保存する【前編】

プログラミング

こんにちは。
今回はwebアプリ制作の第3回ということで、ついに投稿機能を実装していきます。
そのためにSupabaseというサービスを使って、投稿とデータベースへの保存を可能にしていきます。
量が多いので、前編、中編、後編の3部構成になっております。

Supabaseとは?

Supabase は、Firebase の代替として使われる オープンソースのバックエンドサービス です。

以下のような機能を提供してくれます:

  • PostgreSQL データベース(SQLベースのデータ管理)
  • 認証機能(Auth)(ユーザーログイン・管理)
  • リアルタイムデータ更新(データが変わると自動で画面更新)
  • ストレージ(画像やファイルをアップロード)

Supabaseを使うことで、投稿内容をデータベースに保存し、後で一覧表示できる ようになります。

Supabase プロジェクトを作成

① Supabase のアカウント作成

  1. Supabaseの公式サイト にアクセス
  2. 「Start your project」 をクリック
  3. GitHub でログイン(またはアカウント作成)

② 新しいプロジェクトを作成

  1. 「New Project」 をクリック
  2. プロジェクト名 を入力(例: my-app)
  3. データベースのパスワードを設定(忘れないようにメモ)
  4. リージョンは「Northeast Asia(日本)」を選択
  5. 「Create new project」をクリック

👉 プロジェクトが作成されるまで数分かかるので、少し待つ。

環境変数を設定

① APIキーを取得

  1. Supabaseの 「Settings → Data API」 に移動
  2. 「Project URL」 と 「anon public key」 をコピー

 👀 取得する情報

  • Supabase URL(例: https://xyzcompany.supabase.co)
  • anon public key(例: eyJhbGciOiJIUzI1NiIsInR…)

② .env.local に追加

Next.js プロジェクトの .env.local を開いて、以下の内容を追加します。

NEXT_PUBLIC_SUPABASE_URL=https://xyzcompany.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR...

👉 NEXT_PUBLIC_ をつけることで、フロントエンドから直接利用可能になる。
👉 .env.local を変更したら、Next.js の開発サーバーを再起動 する必要があるので、ターミナルで以下のコマンドを入力。

npm run dev

Supabase のパッケージをインストール

Supabase を Next.js で使うために、ターミナルから@supabase/supabase-js をインストールします。

npm install @supabase/supabase-js

Supabase クライアントを作成

Supabaseを使うための クライアント(接続設定) を作成します。

lib/supabase.ts を作成

lib/supabase.ts を新しく作成し、以下のコードを追加:

import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

💡 ここでのポイント

  • createClient() を使って Supabase に接続
  • .env.local から URL と API キーを取得
  • supabase オブジェクトをエクスポートし、どこでも使えるようにする

Clerk の JWT Templates 設定

JWTについて詳しく解説(クリックで展開)


JWT(JSON Web Token)とは?

  • JWT(JSON Web Token) は、認証情報を安全にやり取りするための「デジタル証明書」 です。
  • これは 「このユーザーは本当に正しいログインユーザーです!」という証拠 を表すもの。
  • これがあることで、「この JWT を持っている人=Clerk にログイン済みのユーザー」として Supabase に認識されます。

なぜ Clerk の JWT Templates 設定が必要なの?

  • Clerk でログインしただけでは、その情報を Supabase は知らない!
  • Clerk のユーザーを Supabase でも認証できるようにするため、JWT Templates を作成する!

Clerk → Supabase への認証の流れ

  1. ユーザーが Clerk でログインする
  2. getToken({ template: “supabase” }) で Clerk から Supabase 用の JWT を取得
  3. その JWT を API の Authorization ヘッダーに付けて送信
  4. Supabase がその JWT を検証し、「このユーザーは認証済みだ!」と判断

✅ このために、Clerk 側で Supabase 用の JWT を発行する「JWT Templates」を作成する!

設定手順

  1. Supabase の「Project Settings」→「Data API」の JWT Settings から JWT Secret をコピー
  2. Clerkのダッシュボード にアクセス
  3. 「JWT Templates」 に移動
  4. 「New JWT Template」 を作成
  5. 以下のように設定
  • Template Name: supabase
  • Claims:
{
	"role": "authenticated",
	"email": "{{user.primary_email_address}}",
	"user_id": "{{user.id}}"
}
  • Signing key: 先ほどコピーした JWT Secret をペースト
  • 「Save」 をクリック

こんな感じです。

項目説明
Template Name: supabaseClerk で JWT を発行するときのテンプレート名
Claims:JWT に含める情報(Supabase に送るユーザー情報)
role: “authenticated”Supabase に「このユーザーは認証済み」と伝える
email: {{user.primary_email_address}}JWT にユーザーのメールアドレスを含める
user_id: {{user.id}}Clerk の userId(user_xxxxxx の形式)を含める
Signing key(署名キー)Supabase の JWT Secret を登録(これがないと Supabase で JWT を検証できない)
  1. この設定が完了すると、Clerk の getToken({ template: “supabase” }) を使った際に Supabase 用の JWT が取得できるようになります。

Supabase のデータベースを設定

テーブルを作成

  1. Supabaseのダッシュボード にアクセス
  2. 「Database」 → 「Tables」 → 「New Table」 をクリック
  3. 以下のようにテーブルを2つ作成します:

1つ目のテーブル名:users

以下の二つの項目にはチェックしない ❌

❌ Enable Row Level Security (RLS) (Recommended)
Restrict access to your table by enabling RLS and writing Postgres policies.

❌ Enable Realtime
Broadcast changes on this table to authorized subscribers

テーブルは以下のように作成して下さい。

Column NameTypeDefault ValuePrimary KeyIs NullableIs UniqueDefine as Array
idUUIDgen_random_uuid()✅ Yes(自動で No)(自動で Yes)(自動で No)
clerk_idtext(何も設定しない)❌ No❌ No✅ Yes❌ No

Is Nullable, Is Unique, Define as Array は Primary Key を 「No」 に設定すると右に出てくる歯車から設定して下さい。

2つ目のテーブル名:post

以下の二つの項目にチェック ✅

✅ Enable Row Level Security (RLS) (Recommended)
Restrict access to your table by enabling RLS and writing Postgres policies.

✅ Enable Realtime(こっちはチェックしてもしなくてもいいです)
Broadcast changes on this table to authorized subscribers

テーブルは以下のように作成して下さい。

Column NameTypeDefault ValuePrimary KeyIs NullableIs UniqueDefine as Array
idUUIDgen_random_uuid()✅ Yes(自動で No)(自動で Yes)(自動で No)
user_idtext(何も設定しない)❌ No❌ No❌ No❌ No
contenttext(何も設定しない)❌ No❌ No❌ No❌ No
created_attimestamptznow()❌ No❌ No❌ No❌ No
  1. 「Save」 を押してテーブルを作成

Supabase の SQL で外部キーを設定

SQLについて詳しく解説(クリックで展開)


SQL(Structured Query Language)とは?

  • SQL(エスキューエル) とは、データベースを操作するための言語 です。
  • Supabase では、データベースに保存されたデータを操作するために SQL を使います!
  • Supabase の「SQL Editor」 で SQL コマンドを実行できます!

SQL を使うと、次のような操作が可能になります。

操作SQL コマンド例
データを取得SELECTSELECT * FROM users;
データを追加INSERTINSERT INTO users (clerk_id) VALUES (‘user_123’);
データを更新UPDATEUPDATE users SET clerk_id = ‘user_456’ WHERE clerk_id = ‘user_123’;
データを削除DELETEDELETE FROM users WHERE clerk_id = ‘user_123’;
テーブルを作成CREATE TABLECREATE TABLE users (id UUID PRIMARY KEY, clerk_id TEXT);
外部キーを追加ALTER TABLEALTER TABLE hitorigoto ADD CONSTRAINT fk_hitorigoto_user FOREIGN KEY (user_id) REFERENCES users (clerk_id);

Supabase の「SQL Editor」とは?

Supabase には「SQL Editor」という機能があり、SQL コードを実行できます!

「SQL Editor」の開き方

  1. Supabase ダッシュボード にログイン
  2. 「Database」 → 「SQL Editor」 をクリック
  3. SQL コードを入力して実行できる!

外部キーとは?

  • 外部キー(Foreign Key, FK) とは、あるテーブルのカラムを 別のテーブルのカラムと関連付ける仕組み です。
  • 外部キーを設定することで、データの整合性が保証されます。

例:post.user_id を users.clerk_id と関連付ける(2つのテーブルのidを繋いでいる)

この関係を作る理由

  • post(投稿データ)の user_id が 必ず users テーブルに存在する clerk_id であることを保証
  • 不正な user_id のデータが入らないようにする
  • ユーザーが削除されたら、その人の投稿も削除されるようにする

Supabase の「SQL Editor」を開いて、以下の手順で SQL を実行!

  1. Supabase ダッシュボードにログイン
  2. 「Database」 → 「SQL Editor」 を開く
  3. 以下の SQL を入力
ALTER TABLE public.post
ADD CONSTRAINT fk_post_user
FOREIGN KEY (user_id)
REFERENCES public.users (clerk_id)
ON DELETE CASCADE;
  1. 「Run」ボタンをクリック
  2. これで成功すれば、post.user_id は users.clerk_id に紐づくようになります

この SQL の意味

コマンド説明
ALTER TABLE public.postpost テーブルの定義を変更する
ADD CONSTRAINT fk_post_userpost テーブルに fk_post_user という外部キー制約を追加
FOREIGN KEY (user_id)post の user_id を外部キーとして設定
REFERENCES public.users (clerk_id)user_id は users テーブルの clerk_id に紐づける
ON DELETE CASCADEusers.clerk_id のユーザーが削除されたら、関連する post のデータも削除する

これにより、post.user_id は users.clerk_id に存在するデータしか保存できなくなります。

RLS(Row Level Security)ポリシーを適用

RLS とは?

  • Row Level Security(RLS) は、テーブルのデータを特定のユーザーしか操作できないようにする 仕組み。
  • Supabase では 「RLS を有効化しないと、誰でもデータを読み書きできる」 ため、必ず RLS を設定する必要がある。

RLS を設定しない場合の問題点

状況問題点
RLS を設定しないすべてのユーザーが post の投稿を自由に操作できる
他のユーザーの投稿を削除可能他のユーザーの投稿を簡単に削除できてしまう
不正な user_id の投稿ができるuser_id に誰の id でも入力できるため、不正データが入りやすい

RLS を有効にすることで、ユーザーごとのアクセス制御が可能になる!

SQL で INSERT の RLS ポリシーを設定

投稿を行うときに、ログインしているユーザーだけが hitorigoto に INSERT できるようにします。

CREATE POLICY "Allow Insert for Authenticated Users"
ON public.post
FOR INSERT
TO authenticated
WITH CHECK (
    EXISTS (
        SELECT 1 FROM users WHERE users.clerk_id = post.user_id
    )
);

この SQL の意味

コマンド説明
CREATE POLICY “Allow Insert for Authenticated Users”新しい RLS ポリシーを作成(名前: Allow Insert for Authenticated Users)
ON public.postpost テーブルに適用
FOR INSERTINSERT(データの追加) に適用
TO authenticated認証済みユーザー(authenticated) のみに適用
WITH CHECK (…)条件を満たした場合のみ INSERT を許可
EXISTS (…)users.clerk_id に post.user_id が存在する場合のみ許可
  • この設定により、users.clerk_id に存在しない user_id では INSERT できない!
  • Clerk の userId を users.clerk_id に登録しているユーザーだけが投稿できる!

セットアップ完了

これで投稿機能実装の前編が終了です!
今回はSupabaseのセットアップとClerkとの連携を実装しました。
残り2回でこの内容を反映させるコードを書いていきます。

コメント

タイトルとURLをコピーしました