Supabaseで未ログインの人を管理者にし、その画面を本番で機械確認する(PKCEログインでもOK)
初回ログインでusers行を作るアプリで、本人のログインを待たずに管理者を用意し、magiclink→verifyOtp→cookie注入のPlaywrightで管理者画面を検証する手順
約5.2万トークンの節約 (API料金換算で約78円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「Supabaseで未ログインの人を管理者にし、その画面を本番で機械確認する(PKCEログインでもOK)」は、Web開発カテゴリのAI指示書(MDファイル)です。初回ログインでusers行を作るアプリで、本人のログインを待たずに管理者を用意し、magiclink→verifyOtp→cookie注入のPlaywrightで管理者画面を検証する手順この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約5.2万トークン(API料金換算で約78円)・87%のトークンを節約できます。
- カテゴリ
- Web開発
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約6万トークン
- この巻物使用時
- 約8,000トークン
- 節約量
- 約5.2万トークン (約78円)
- 更新日
- 2026-10-18
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/supabase-pkce-ok/raw を読み込んで、この指示書どおりに実装して"
中身
Supabase アプリで「まだ一度もログインしていない人」を管理者にし、その画面を本番で確認する
Google ログイン(OAuth / PKCE)で初回ログイン時にユーザー行を自動作成するアプリでは、 本人が一度ログインするまで users 行が存在せず、権限を付けられない。 この指示書は、本人のログインを待たずに管理者権限を用意し、 その権限で本番画面が正しく出ることを機械的に確認する手順。
前提(AI が最初に確認すること)
- ログイン時のプロビジョニング処理を読む。典型は次の形:
exchangeCodeForSession(code)→usersをid = auth.uidで検索 → 行があればそのまま通す/無ければrole='staff'で insert- この「既存行があれば通す」分岐が無いと本手順は使えない(上書きされる)。
- 権限を変える画面が本当に無いかをコード検索で確かめる(例:
usersのroleを update する処理の grep)。無いことを根拠付きで報告する。 - 対象メールが許可ドメイン/許可リストに入っているかを確かめる。
手順 1: 認証アカウントと users 行を先に作る(service role)
import { createClient } from '@supabase/supabase-js';
const s = createClient(SUPABASE_URL, SERVICE_ROLE_KEY, { auth: { persistSession: false } });
const EMAIL = '<対象メール>';
// 既存の認証アカウントを全ページ走査(重複作成を防ぐ)
let found = null;
for (let page = 1; page < 50 && !found; page++) {
const { data } = await s.auth.admin.listUsers({ page, perPage: 200 });
found = data.users.find((u) => u.email?.toLowerCase() === EMAIL) ?? null;
if (data.users.length < 200) break;
}
if (!found) {
const { data } = await s.auth.admin.createUser({ email: EMAIL, email_confirm: true });
found = data.user;
}
// users 行(アプリ側の権限テーブル)を管理者で作る/既存なら role だけ上げる
const existing = await s.from('users').select('id, role').eq('id', found.id).maybeSingle();
if (!existing.data) {
await s.from('users').insert({ id: found.id, email: EMAIL, name: '<表示名>', org_id: '<組織ID>', role: 'admin', is_active: true });
} else if (existing.data.role !== 'admin') {
await s.from('users').update({ role: 'admin' }).eq('id', found.id);
}
// 必ず read-back
const back = await s.from('users').select('email, role, is_active').eq('id', found.id).single();
email_confirm: trueにしておくと、後日の Google ログインで同じ確認済みメールの既存ユーザーに自動でつながる(Supabase の標準挙動)。 ただし実際の Google ログインでの確認は本人にしかできないので、報告では「未確認」と明記し、エラー時は画面文言をもらう段取りにする。- 戻し方(role を staff に戻す1行)も報告に添える。
手順 2: その権限で本番画面を開いて確認する
本番ログインが PKCE の code 方式だと、generateLink が返すマジックリンク URL をブラウザで開いてもコールバックで弾かれる。
セッションを API で作り、@supabase/ssr が読む cookie を直接入れる。
import { chromium } from '@playwright/test';
const { data: link } = await s.auth.admin.generateLink({ type: 'magiclink', email: EMAIL }); // メールは送られない
const pub = createClient(SUPABASE_URL, ANON_KEY, { auth: { persistSession: false } });
const { data: v } = await pub.auth.verifyOtp({ type: 'magiclink', token_hash: link.properties.hashed_token });
const ref = new URL(SUPABASE_URL).hostname.split('.')[0];
const value = 'base64-' + Buffer.from(JSON.stringify(v.session)).toString('base64url');
const chunks = value.match(/.{1,3180}/g); // 大きい場合は .0 .1 … に分割される
const cookies = (chunks.length === 1
? [[`sb-${ref}-auth-token`, value]]
: chunks.map((c, i) => [`sb-${ref}-auth-token.${i}`, c]))
.map(([name, val]) => ({ name, value: val, domain: '<本番ホスト>', path: '/', secure: true, sameSite: 'Lax' }));
const browser = await chromium.launch();
const ctx = await browser.newContext();
await ctx.addCookies(cookies);
const page = await ctx.newPage();
await page.goto('https://<本番ホスト>/<管理者画面>');
console.log(await page.getByRole('button', { name: '<管理者だけに出るボタン>' }).isVisible());
await s.auth.admin.signOut(v.session.access_token).catch(() => {}); // 後始末
await browser.close();
- 判定は「管理者だけに出る要素が見える」ことで行う(URL が 200 なだけでは不可)。
- 秘匿値は
.env.local等からプロセス内で読み、標準出力に出さない。
やってはいけない
- 本人のログインを待つためだけに user に「一度ログインして」と頼む(手順 1 で不要になる)。
- 管理者画面の確認を user のスクリーンショットに頼む(手順 2 で機械確認できる)。
- 共有アカウントにパスワードログインを追加して確認する(不要な認証経路が増える)。
listUsersを1ページ目だけ見て「存在しない」と判断する。
よくある質問
+「Supabaseで未ログインの人を管理者にし、その画面を本番で機械確認する(PKCEログインでもOK)」とは何ですか?
初回ログインでusers行を作るアプリで、本人のログインを待たずに管理者を用意し、magiclink→verifyOtp→cookie注入のPlaywrightで管理者画面を検証する手順
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約6万トークンかかりますが、この巻物を使えば約8,000トークンで済みます。差し引き約5.2万トークン(API料金換算で約78円)・87%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
Next.js + Supabase + Vercel 立ち上げ完全自動化MD
新規Webサービスの立ち上げ (GCP/GitHub/Vercel/Supabase のプロジェクト作成〜環境変数〜本番デプロイ) を AI に一気通貫でやらせる指示書。人間の作業はログイン1回だけ。
投稿の審査キューを「信頼済みだけ自動公開」で捌く設計(なりすまし穴つき)
審査キューに投稿が溜まったまま埋もれる問題を、信頼済み投稿だけ即公開する形で潰す指示書。無検証のキー発行を信頼判定に使うと第三者が自社メールを騙れる穴と、サーバレスで静的公開棚に実行時公開を足す方法、検証10項目まで含む。
Vercel の Sensitive 環境変数が誰にも読み戻せない状態を作り直さずに解消し、Development 正本+毎日の差分監視で恒久化する
本番 env が全て Sensitive で共有不能なとき、skip-domain の一時本番デプロイ+RSA 暗号化で1回だけ取り出し、Development を正本化、env:set 入口と GitHub Actions の parity 監視で再発を止める手順
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア