マキモノ
Web開発無料✅ 公式検証済みv1.0.0 / 更新

Supabaseで未ログインの人を管理者にし、その画面を本番で機械確認する(PKCEログインでもOK)

初回ログインでusers行を作るアプリで、本人のログインを待たずに管理者を用意し、magiclink→verifyOtp→cookie注入のPlaywrightで管理者画面を検証する手順

出品者: cr@orgiast.jp📖 読込 約1,946トークン (約3円)💰 コスパ 27倍
トークン節約メーター87%節約
ゼロからAIに作らせた場合約6万トークン
このMDを読ませた場合約8,000トークン

約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 のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/supabase-pkce-ok/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

Supabase アプリで「まだ一度もログインしていない人」を管理者にし、その画面を本番で確認する

Google ログイン(OAuth / PKCE)で初回ログイン時にユーザー行を自動作成するアプリでは、 本人が一度ログインするまで users 行が存在せず、権限を付けられない。 この指示書は、本人のログインを待たずに管理者権限を用意し、 その権限で本番画面が正しく出ることを機械的に確認する手順。

前提(AI が最初に確認すること)

  1. ログイン時のプロビジョニング処理を読む。典型は次の形:
    • exchangeCodeForSession(code) → users を id = auth.uid で検索 → 行があればそのまま通す/無ければ role='staff' で insert
    • この「既存行があれば通す」分岐が無いと本手順は使えない(上書きされる)。
  2. 権限を変える画面が本当に無いかをコード検索で確かめる(例: users の role を update する処理の grep)。無いことを根拠付きで報告する。
  3. 対象メールが許可ドメイン/許可リストに入っているかを確かめる。

手順 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で頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア