SupabaseがApp Routerに対応しているのを今更知ったので試してみた
イントロ
SupabaseがApp Routerに対応してるのを今更知りました。
以下の記事は2023-08-10
のものなので、かなり長い間、無駄なことをしてました。
ということで、今日は、App Routerに対応した(していた)SupabaseでのAuth系の実装方法を試してみようと思います。
We generally recommend using the new @supabase/ssr package instead of auth-helpers. @supabase/ssr takes the core concepts of the Auth Helpers package and makes them available to any server framework.
とのことなので、@supabase/ssr
を使って実装していこうと思います。
本題
環境構築
リポジトリの作成
ハリボテTODOアプリをテンプレートとしてリポジトリを作成します。
できました。
作成したリポジトリをクローン
git clone git@github.com:shinaps/nextjs-approuter-supabase-todoapp.git
Cloning into 'nextjs-approuter-supabase-todoapp'...
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
remote: Enumerating objects: 44, done.
remote: Counting objects: 100% (44/44), done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 44 (delta 0), reused 42 (delta 0), pack-reused 0
Receiving objects: 100% (44/44), 71.36 KiB | 445.00 KiB/s, done.
ハリボテTODOアプリ起動
npm install
npm run dev
Supabaseでプロジェクトを作成
実装
以下のページを参考に実装していきます。
パッケージのインストール
npm install @supabase/ssr
環境変数の設定
https://supabase.com/dashboard/project/{Reference ID}/settings/api
のURLにアクセスしてProject URLとProject API keysのanon key
を.env.local
に転記します。
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
以下の手順は今回はスキップ可能です。スキップする場合はcreateBrowserClient<Database>
をcreateBrowserClient
のように書き換えて使用してください。
Supabaseの型情報をクライアントで使用できるようにする(オプショナル)
Supabaseの型情報を生成
npm install supabase
npx supabase login
supabase init
supabase link --project-ref {Reference ID}
supabase gen types typescript --linked > supabase/database.types.ts
これでsupabase/database.types.ts
に型の情報が生成されます。
supabase link --project-ref {Reference ID}
の時にDBのパスワードが求められるので、忘れてしまった場合は以下のボタンをクリックすればリセットできます。
https://supabase.com/dashboard/project/{Reference ID}/settings/database
のURLからページにアクセスできます。
clientに型情報を追加
以下のようにジェネリック型にDatabaseという型を渡すことで、データベースの型を参照できるようになります。
import { createBrowserClient } from "@supabase/ssr";
import { Database } from "../../../supabase/database.types";
export const createClient = () => {
return createBrowserClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);
};
クライアントの作成
今回は1種類(Server ActionsとRoute Handlersで使用するクライアント)しか作成する必要はありませんが、実際にアプリケーションで使用する場合は、3種類作成することになると思います。その3種類というのは以下の3つです。
- Client Componentsで使用するクライアント
- Server Componentsで使用するクライアント
- Server ActionsとRoute Handlersで使用するクライアント
サーバーサイドで使用するクライアントが2種類あるのは以下のように、Server ComponentsではCookieの書き込みができないという特徴があるからです。
Cookieの読み取り | Cookieの書き込み | |
---|---|---|
Server Components | できる | できない |
Route Handlers | できる | できる |
Server Actions | できる | できる |
Server ActionsとRoute Handlersで使用するクライアントにはcookie-writable-server-client.ts
という名前をつけましたが、他にいい名前があればそれを使用してください。
ミドルウェアの作成
ミドルウェアでは Cookieの情報を使用してuserの情報を取得し、userが取得できない場合はサインインのページにリダイレクトする処理になっています。
プロバイダーの設定
今回はメールアドレスの検証の実装は行わないので、
https://supabase.com/dashboard/project/{Reference ID}/auth/providers
のURLにアクセスし、Auth Providers
> Email
> Confirm email
をOFFにします。
Confirm email
がON
になっている場合、メールアドレスの確認が完了していないユーザーはサインアップできていてもNULLになるので気をつけてください。
サインイン用のactionを作成
自分はわかりやすいのでsrc/app/services/auth/sign-in.action.ts
という名前にして関数名にもAction
をつけてますが、action
を付けないといけないという決まりはありません。
サインアップ用のactionを作成
サインイン用のactionとほぼ同じです。
サインイン用のページを作成
プログレッシブエンハンスメントは捨てました。use client
を使います。
ここは以下のページを見ていただければわかると思うので、説明は省きます。
わからなかったらコメントかDMしてください。
終わり・感想
サーバーサイドでのセッションの管理や検証が簡単に実装できるようになっててすごく便利です!
こちらのページでもサンプルコードや解説が充実しててわかりやすかったです。
Discussion