Remix で Supabase 入門 – 匿名認証を試してみる
こんにちは。Gaji-Laboの村上です。
最近、個人開発で Remix と Supabase を組み合わせたプロジェクトを進めています。
今回は、その開発中に学んだ Supabase の匿名認証を活用して、簡単なユーザー認証機能を実装する方法を紹介します。
最終的には、Supabase のダッシュボードでユーザー情報が登録されていることを確認するところまでを進めます。
使用技術
技術 | バージョン |
---|---|
node | 20.18.0 |
npm | 10.8.2 |
remix | 2.12.1 |
supabase | 1.204.3 |
Remix の準備
プロジェクトの作成
プロジェクト名は remix-supabase-anonymous
とします。
npx create-remix@latest remix-supabase-anonymous
cd remix-supabase-anonymous
npm run dev
コマンド実行後、http://localhost:5173/ が表示できれば OK です。
デフォルト状態から調整
/app/root.tsx
と /app/routes/_index.tsx
から不要なものを削除し、以下のように調整します。
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import "./tailwind.css";
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
import type { MetaFunction } from "@remix-run/node";
export const meta: MetaFunction = () => {
return [
{ title: "New Remix App" },
{ name: "description", content: "Welcome to Remix!" },
];
};
export default function Index() {
return (
<main className="p-6">
<h1 className="mb-1">TOP PAGE</h1>
<p>texttexttext</p>
</main>
);
}
Supabase のローカル環境を構築する
Supabase をローカルで動かすには、Docker が必要です。
Docker については、公式ガイドに従って Docker Desktop をインストールして設定してください。
ローカル環境の構築は、Supabase Local Development & CLIに則って進めます。
Supabase CLI のインストール
npm install supabase --save-dev
Supabase プロジェクトの初期化
npx supabase init
Generate VS Code settings for Deno? [y/N]
Generate IntelliJ Settings for Deno? [y/N]
Deno を使わない方は N で enter を押下してください。
これで supabase ディレクトリと設定ファイル等が作成されます。
Supabase の起動
npx supabase start
初回起動時は少し時間がかかります。No seed files matched pattern: supabase/seed.sql
から進まないときは、Docker を再起動してみてからもう一度 npx supabase start してみてください。
起動後、ターミナルに表示されるanon key
をコピーしておきます。
http://localhost:54323/ にアクセスし、Supabase のダッシュボードが表示されていれば起動確認完了です。
匿名認証を許可する
デフォルト設定では、匿名認証が無効になっています。
そのため、ローカルで開発する場合は supabase/config.toml
ファイルの enable_anonymous_sign_ins を true に変更します。
# Allow/disallow anonymous sign-ins to your project.
enable_anonymous_sign_ins = true
設定を変更後、Docker を再起動します。
npx supabase stop
npx supabase start
Supabase クライアントを作成
パッケージをインストール
npm install @supabase/ssr @supabase/supabase-js
環境変数を設定
.env.local
を作成して、SUPABASE_URL
と SUPABASE_ANON_KEY
を設定します。SUPABASE_ANON_KEY
は、コピーしておいた anon key
を使います。
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cXXXXXXXX
Supabase クライアントを作成する supabase.server.ts を準備
import { createServerClient, parseCookieHeader, serializeCookieHeader } from "@supabase/ssr";
/**
* Supabaseクライアントを作成する関数。
*
* @param {Request} request - クライアントからのリクエストオブジェクト。
* @returns {{ supabase: any, headers: Headers }} Supabaseクライアントとヘッダーオブジェクトを含むオブジェクト。
*
* @example
* ```typescript
* const { supabase, headers } = supabaseClient(request);
* ```
*/
export const supabaseClient = (request: Request) => {
const headers = new Headers();
const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_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 { supabase, headers };
}
ログイン・ログアウトの実装
ログイン機能の実装
ログイン機能の実装のために、app/routes/signin.tsx
ファイルを作成します。
import { type ActionFunctionArgs, redirect } from "@remix-run/node";
import { supabaseClient } from "~/services/supabase.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { supabase, headers } = supabaseClient(request);
// Supabase で匿名ログインを実行
const { error } = await supabase.auth.signInAnonymously();
if (error) {
return { error: error.message };
}
return redirect("/", {
headers,
});
};
ログアウト機能の実装
ログアウト機能の実装のために、app/routes/signout.tsx
ファイルを作成します。
import { type ActionFunctionArgs, redirect } from "@remix-run/node";
import { supabaseClient } from "~/services/supabase.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { supabase, headers } = supabaseClient(request);
// Supabase でログアウトを実行
const { error } = await supabase.auth.signOut();
if (error) {
return { error: error.message };
}
return redirect("/", {
headers,
});
};
ログイン・ログアウトの組み込み
app/routes/_index.tsx
にログインボタンとログアウトボタンを組み込みます。
ログインしている時は、Welcome, {user.id}
と表示されるようになっています。
import { type MetaFunction, type LoaderFunctionArgs } from "@remix-run/node";
import { Form, json, useLoaderData } from "@remix-run/react";
import { supabaseClient } from "~/services/supabase.server";
export const meta: MetaFunction = () => {
return [
{ title: "New Remix App" },
{ name: "description", content: "Welcome to Remix!" },
];
};
export const loader = async({ request }: LoaderFunctionArgs) => {
const { supabase } = supabaseClient(request);
const { data: { user } } = await supabase.auth.getUser();
return json({ user });
}
export default function Index() {
const { user } = useLoaderData<typeof loader>();
return (
<main className="p-6">
<h1 className="mb-1">TOP PAGE</h1>
<p>texttexttext</p>
<Form action="/signin" method="post">
<button type="submit">ログイン</button>
</Form>
<Form action="/signout" method="post">
<button type="submit">ログアウト</button>
</Form>
{user && <p>Welcome, {user.id}</p>}
</main>
);
}
http://localhost:5173/
ログインボタンを押下して、下記のように表示されればログイン成功です。
Supanase のダッシュボードで確認
http://localhost:54323/project/default/auth/users にアクセスします。
http://localhost:5173/ で表示されていた id に該当する user が登録されていることが確認できます。
以上で匿名認証の実装は完了です。
参考
Creating a Supabase client for SSR | Supabase DOCS
Anonymous Sign-Ins | Supabase DOCS
最後に
今回紹介した匿名認証機能をベースに、メール認証や OAuth 認証など、他の認証方法も試してみると、より実践的なアプリケーションを構築することができます。
Remix と Supabase の組み合わせは MVP 開発やスピード感の求められるプロジェクトでは選択肢のひとつになりそうです!
Gaji-Labo では、Remix をはじめとしたフロントエンド技術を活用し、スタートアップのプロダクト開発を支援していますので、フロントエンド開発で課題があればお気軽にお問い合わせください。
Gaji-Labo フロントエンドエンジニア向けご案内資料
Gaji-Labo は Next.js, React, TypeScript 開発の実績と知見があります
フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。
「既存のサイトを Next.js に移行したい」
「人手が足りず信頼できるエンジニアを探している」
「自分たちで手を付けてみたがいまいち上手くいかない」
フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。
オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。
Next.js, React, TypeScript の相談をする!