◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/アプリ開発
◇ アプリ開発/2026-06-24中級

Next.js × Supabase で必ず向き合う3つの実装 — RLS・状態管理・リアルタイム更新

Webアプリの土台を組んだ先で必ず詰まる3つ、DBのアクセス制御(RLS)・画面の状態管理・リアルタイム更新を、Next.jsとSupabaseのコードを交えて実装レベルで解説します。購読の解除忘れによるメモリリークや、認証とRLSの連動といった、本番でハマる落とし穴まで。

Next.js3Supabase37RLS3状態管理12リアルタイム7認証15premium3

✦ プレミアム記事

前編では、Webアプリの全体像と、土台をBaaSに任せるところまでを地図として描きました。後編は、その土台の上で必ず向き合うことになる3つの実装に踏み込みます。DBのアクセス制御、画面の状態管理、そしてリアルタイム更新です。どれも「動くものは作れたが、本番に出す前に詰まる」典型でした。

私自身、個人開発でアプリの裏側を組むとき、この3つでそれぞれ別のハマり方をしました。順に、コードを交えて整理します。

なぜ「誰でもDBを直接叩ける」のは危険なのか

BaaSの便利さの裏返しが、ブラウザから直接DBを呼べてしまうことです。これは「悪意のある人が他人のデータも見えるのでは」という当然の不安につながります。その不安は正しく、ここで効くのが RLS(Row Level Security、行レベルセキュリティ)です。

RLSは「テーブルの各行に対して、誰がアクセスできるかをDB自体に設定する」機能です。クエリ自体は誰が送っても同じですが、RLSが送信者を見て、返す行を自動で絞り込みます。

-- 「自分が作成したタスクしか見えない」をDBレベルで強制する
alter table tasks enable row level security;
 
create policy "自分のタスクのみ参照可能"
  on tasks for select
  using (auth.uid() = owner_id);

普通のプログラミングでは「アクセス制御はアプリのコード(if文)で書く」と考えがちですが、BaaSの世界ではDB自体にルールを持たせます。これにより、フロントのコードにバグがあっても、DBレベルで他人のデータの漏洩を防げます。私のお勧めは、「テーブルを作ったらRLSを有効にしてポリシーを書く」までを必ず1セットの作業にすることです。後回しにすると、そのまま本番に出て事故になります。

認証とRLSは同じトークンで連動している

RLSのポリシーに出てきた auth.uid() の中身は、ログイン状態を表すトークンそのものです。ログイン機能を自作するのは大変ですが、BaaSを使うとライブラリのように扱えます。

// ログイン
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password123',
});
 
// 現在ログイン中のユーザーを取得
const { data: { user } } = await supabase.auth.getUser();

知っておくと整理しやすいのは、ログイン状態がブラウザに保存されるトークンで管理されている、という点です。ログイン時に受け取ったトークンをブラウザが保持し、以降のリクエストで一緒に送ることで、サーバーに「ログイン済みのこのユーザーだ」と伝えます。このトークンが、先ほどのRLSの auth.uid() の中身です。つまり認証とRLSは、同じトークンを通じて連動しています。ここがつながって見えると、アクセス制御の全体像が一気に腑に落ちます。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦ブラウザから直接DBを叩く構成で他人のデータを守るRLSポリシーの書き方と、認証トークンとの連動
✦propsのバケツリレーを避けるグローバル状態管理(Zustand)の最小実装と使い分けの基準
✦Realtime購読の解除忘れによるメモリリークを防ぐ、useEffectクリーンアップの具体コード
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

◇ アプリ開発2026-09-29
起動のたびに一瞬ログイン画面が出る expo-router アプリを、Protected routes と「まだ分からない」の三状態で組み直す
ログイン済みなのに起動直後にログイン画面が一瞬出る、ログアウトしても画面が変わらない。expo-router の Protected routes に Supabase の認証状態を「不明」込みの三つで渡し、_layout.tsx の置き場所まで含めて直した手順です。
◇ アプリ開発2026-10-15
購読が切れても広告が戻りませんでした。「いま ad-free でなければ false」と書いていた、判定の向きを直した記録
購読が失効しても広告非表示のままになる不具合の原因は、判定の向きの逆転でした。二系統の購入確認を待って合成し、失敗した回は前回を保つ部品を、手元で動かして確かめた記録です。
◇ アプリ開発2026-10-15
adjustsFontSizeToFit で特定の1行だけ極小になるとき、疑うのは文字列ではなく枠の高さです
一覧の10行目だけ文字が4ptまで縮む。データも文字列も正常なのに起きる iOS の症状を、Yoga の丸めと縮小判定のソースで確かめ、Node で再現率を数えた記録です。