Remixで@supabase/ssrを使ったログイン処理を実装する

サーバー側の処理を利用して、Supabaseのログイン処理をRemixに実装する方法についてまとめました。 @supabase/ssrを使うことで、Cloudflare Pages上でクライアントを作成し、Cookieに関する処理を行います。ログイン処理後は、作成したクライアントを使用してCookieに情報を設定し、ログイン画面から移動できるようにします。さらに、参考資料に従い、ログイン処理を実装します。

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

目次

    サーバー側の処理を利用して、Supabaseのログイン処理をRemixに実装する方法を簡単にまとめました。

    やりたかったこと

    Remixのactionを使ってログイン処理を実行する方法を、Supabase Authで実現したい。

    サーバー側の処理を実装する場合は、@supabase/ssrを使う

    ドキュメントに紹介されていたライブラリなので、素直に従うことにします。今回Cloudflare Pagesで実装しますので、次のようなクライアントを作成する関数を用意しました。ポイントとしてはCookieに関する処理を含めるところでしょうか。

    import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
    
    export const createSupabaseServerClient = ({context, request}: {
        context: {
            cloudflare: {
                env: Pick<Env, 'SUPABASE_KEY' | 'SUPABASE_URL'>
            }
        },
        request: Request
    }, headers: Headers) => {
        const supabaseClient = createServerClient(
          context.cloudflare.env.SUPABASE_URL, 
          context.cloudflare.env.SUPABASE_KEY, {
          cookies: {
            getAll() {
              return parseCookieHeader(request.headers.get('Cookie') ?? '')
            },
            setAll(cookiesToSet) {
              cookiesToSet.forEach(({ name, value, options }) => {
                headers.append('Set-Cookie', serializeCookieHeader(name, value, options))
              })
            }
          },
        })
        return supabaseClient
    }

    Actionでログイン処理を実装する

    あとは先ほど作成したクライアントを利用して、ログイン処理を実装します。ログインに成功した場合、Cookieへその情報を設定する必要がありますので、headerを設定することと、actionの戻り値にheadersを含めることを忘れないようにしましょう。これを忘れてログイン画面から移動できなくなることや、ログイン状態に切り替わらない現象に遭遇しました。

    export async function action({request, context}: ActionFunctionArgs) {
      const headers = new Headers()
      const supabaseClient = createSupabaseServerClient({context, request}, headers)
      const formData = await request.formData();
      const email = formData.get('email');
      const password = formData.get('password');
      if (!email || !password) {
        return json({error: 'error'})
      }
      const data = await supabaseClient.auth.signInWithPassword({ email: email.toString(), password: password.toString() });
    
      if (data.error) {
        return json({ error: data.error.message });
      }
      throw redirect('/mypage/', {
        headers
      })
    }

    参考資料

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