Clerkのユーザー情報を使ってSupabase上にあるDBへのアクセス権を管理する

この記事では、ClerkというIDaaSを利用してユーザー情報を管理している場合に、Supabase上にあるデータベースのRow level Securityを設定する方法が紹介されています。SupabaseのJWTを取得し、Clerkと連携する手順や、Supabaseでの関数作成、テーブル設定、RLSの設定方法が紹介されています。実際に導入しなかったものの、Supabase以外のIDaaSを利用しつつRLSの恩恵を受ける方法について学びました。

広告ここから
広告ここまで

目次

    この記事では、ClerkというIDaaSを利用してユーザー情報を管理している場合に、Supabase上にあるデータベースのRow level Securityを設定する方法を紹介します。Supabase Authを使うケースが多いとは思いますが、Clerkなどの外部IDaaSと組み合わせるケースに遭遇した際の参考になればと思います。またこの記事は、Supabase Advent Calendar 2024の13日目として投稿しました。

    SupabaseでJWTを取得する

    Clerkのユーザー情報をSupabaseのRLSで利用するには、まずSupabase側でJWTを取得します。Project settingsからAPI settingsを開き、JWT Settingsにあるシークレットを取得しましょう。

    このシークレットは作成後再度取得することができません。再発行する必要がありますので、他で使う可能性も考えると厳重に保管しておきましょう。

    ClerkでJWT TemplatesからSupabaseを選ぶ

    JWTはClerkで利用します。Clerk側にJWT Templatesという項目がありますので、ここでNew templateを選びましょう。

    Supabaseがテンプレートとして表示されますので、選択します。

    入力フォームがいくつか表示されます。ここでSigning keyにJWT secretをペーストしましょう。また、AlgorithmがHS256なのも確認して、保存します。

    これで連携準備ができました。

    SupabaseのSQL Editorでfunctionを作成

    次はSupabaseのRLSで利用する関数を作成します。以下のSQLを実行しましょう。Clerk側のユーザーIDを取得するために利用する・・・と自分の中では理解しています。

    create or replace function requesting_user_id()
    returns text
    language sql stable
    as $
      select nullif(current_setting('request.jwt.claims', true)::json->>'sub', '')::text;
    $;
    

    SQL Editorを使うと、簡単にSQLが実行できるので、Supabaseは便利ですね。

    clerk user idを利用するテーブルを作成する

    あとはSupabaseで利用するテーブルを作りましょう。この際、Clerkのuser idをtext型で保存できるように設定しておきましょう。

    RLSを設定する

    最後にテーブルへRLSを設定しましょう。作成した関数でリクエスト時のClerk user idを取得し、read / writeする対象の列にあるclerk_user_idと一致するかを検証するクエリを設定しています。

    readを許可する場合は、次のようなクエリを設定します。

    create policy "Read clerk stripe id mapper table"
    on "public"."clerk_user_stripe_customer"
    as PERMISSIVE
    for SELECT
    to public
    using (
      requesting_user_id() = clerk_user_id
    );

    writeの場合はこうなります。

    create policy "write clerk stripe id mapper table"
    on "public"."clerk_user_stripe_customer"
    as PERMISSIVE
    for INSERT
    to public
    with check (
      (requesting_user_id() = clerk_user_id)
    );

    まとめ

    ここまで調べてテストはしたのですが、Clerkのmetadataで十分なデータしかなかったことが判明し、実際には導入しませんでした。そのため、簡単な手順紹介だけに終わっています。とはいえこのような方法でSupabase以外のIDaaSを利用しつつRLSの恩恵を受けることができることがわかったのは、大きな前進だと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark