【🔰初心者向け】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 ArrayPrimary 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をコピーしました