✨ Supabaseのトークンとuser_metadataの落とし穴:初心者向けガイド

✨ Supabaseのトークンとuser_metadataの落とし穴:初心者向けガイド

投稿日: 2025年07月12日

学習振り返り
Tips
要約
  • Supabaseでは、ユーザーの認証情報としてJWTトークンが発行され、ユーザーのメタデータを含むが、トークンは自動的に更新されないため変更が反映されないことがある。
  • ユーザーがuser_metadataを更新した場合、トークンをリフレッシュする必要があり、手動でセッションを更新する、再ログインさせる、またはデータベースでロールを管理する方法がある。
  • トークンの仕組みを理解し、キャッシュされる可能性を考慮することが重要です。
音声で記事を再生
0:00

✅ はじめに

こんにちは!今回はSupabaseを使った認証アプリ開発で多くの人がつまずく「トークンとユーザーデータの不一致」問題について、初心者向けにわかりやすく解説します。

特に以下のような方におすすめです:

  • user_metadatarole を入れて認可(権限)を管理したい

  • user_metadata を更新したのに画面が反映されない

  • Supabaseのトークンってどう動いてるの?


🔐 Supabaseのトークンとは?

Supabaseでは、ユーザーがログインすると「JWT(JSON Web Token)」というトークンが発行されます。
このトークンには以下の情報が埋め込まれています:

  • ユーザーのID

  • メールアドレス

  • user_metadata(ニックネームやロールなど)

  • トークンの有効期限(例:1時間)

SupabaseのgetUser()などで取得しているのは、このトークンに含まれる情報です。


❗問題:user_metadata を更新しても反映されない!?

たとえば、ユーザーを「一般 → 管理者(role: 'ADMIN')」に昇格したとします。

await supabase.auth.admin.updateUserById(userId, { user_metadata: { role: 'ADMIN' } });

でも…なぜか画面で見ても、まだ role: 'USER' のまま!?


🤔 なぜこうなるの?

それは、SupabaseのgetUser()で取得しているのが“古いトークン”だからです。

  • JWTは一度発行されたら、内容を自動では更新できません。

  • user_metadataを変更しても、トークンが更新されるまでは反映されないのです。


🔄 解決策:トークンをリフレッシュしよう

✅ 方法①:セッションを手動で更新する

await supabase.auth.refreshSession();

これで新しいJWTが発行され、user_metadataも最新になります。


✅ 方法②:再ログインさせる

await supabase.auth.signOut(); await supabase.auth.signInWithPassword({ email, password });

少し強引ですが、確実です。


✅ 方法③(おすすめ):ロールはデータベースで管理!

実は、認可(アクセス制限)にJWTを使うのはあまり安全ではありません
本番環境では、ユーザーの role権限 はデータベースに保存し、常にDBから確認する方が安心です。

// SupabaseからユーザーIDを取得
const { data: { user } } = await supabase.auth.getUser();

// PrismaでDBからユーザーを取得(ロール付き)
const dbUser = await prisma.user.findUnique({
  where: { supabaseUserId: user.id },
  include: { role: true }
});

if (dbUser?.role.name !== 'ADMIN') {
  return res.status(403).json({ error: 'アクセス拒否' });
}

✅ まとめ

✨ Supabaseのトークンとuser_metadataの落とし穴:初心者向けガイド|ShiftBブログ

📌 最後に

Supabaseはとても使いやすいツールですが、「トークンの仕組み」はちょっとした落とし穴があります。

大切なのは「トークンはキャッシュされる。だから最新じゃないこともある」と知っておくこと!

シェア!

Threads
icon
さかした
おじさんでも学べる!をモットーに。 以前はRuby(3年)、今は React / Next.js を中心に、学習中。
Loading...
記事一覧に戻る
Threads
0