SupabaseのAuth Helperを使うときの注意点
筆者もNext.js v13やSupabaseを利用し始めてから日が浅いため、一部未検証な部分があります。
Supabase公式の認証ヘルパーライブラリ
ベータではありますが、Supabase公式からNext.js
をはじめとする幾つかのフレームワーク用に認証のヘルパーライブラリが提供されています。Next.js
では、Next Auth
が認証管理のデファクトスタンダートであると思いますが、Supabase Auth
の機能を活用するなら上記のヘルパーライブラリを用いるように示されています。
Next Authの公式ドキュメントから引用
This adapter is developed by the community and not officially maintained or supported by Supabase. It uses the Supabase Database to store user and session data in a separate next_auth schema. It is a standalone Auth server that does not interface with Supabase Auth and therefore provides a different feature set.
If you’re looking for an officially maintained Auth server with additional features like built-in email server, phone auth, and Multi Factor Authentication (MFA / 2FA), please use Supabase Auth with the Auth Helpers for Next.js.
Supabaseの接続クライアントが色々あって違いがわからない…
公式のドキュメントを見ればわかるのですが、クライアント生成関数が複数存在します。使用する場面を間違えるとエラーはないのにビルドが通らなくなります。そのため、各関数の使い方には注意しなければなりません。
createClient(url, anon)
import { createClient } from '@supabase/supabase-js'
この関数はヘルパーライブラリではなく、supabase-js
からインポートします。ブラウザ、サーバ(Node.js)問わず利用することができます。下記の関数は全てこの関数のラッパーであり、環境の識別や環境変数の自動読み込みをしているようです。ヘルパーライブラリを用いるのであれば、基本的に使用する必要はありません。しかし、SSRする際は認証やリクエストの情報が取得できないため、下記のラッパー関数は使えません。generateStaticParams()
の中でcreateServerComponentSupabaseClient()
を使用するとビルドに失敗します。このような状況では、この関数からクライアントを生成するべきだと思います。
info - Creating an optimized production build
info - Compiled successfully
info - Linting and checking validity of types
info - Collecting page data .Error: Invariant: Method expects to have requestAsyncStorage, none available
...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
> Build error occurred
Error: Failed to collect page data for /supabase/[id]
...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
type: 'Error'
}
info - Collecting page data .%
createBrowserSupabaseClient()
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
ブラウザで利用するクライアント生成関数です。これ経由で取得した認証情報とサーバ側の認証情報が同一か検証する方法が公式ドキュメントで紹介されています。SSRやSSGを考慮しないSPAであれば、これだけで問題ないと思います。
createServerComponentSupabaseClient({ headers, cookies })
import { createServerComponentSupabaseClient } from '@supabase/auth-helpers-nextjs'
Reaxt Server Component
用のクライアント生成関数です。Header
やCookie
からクライアントを生成してくれます。ユーザのセッションも引き継がれるため、行レベルセキュリティ
を導入していれば、ユーザの権限外のデータベース操作は行えないはずです(要検証)。プログラマのミスで他ユーザにまで波及する操作を実装しても、実行時にエラーになるのでプログラムの安全性が向上します。Server Component
が主体のapp
ディレクトリでは、積極的に利用した方が良さそうです。
createServerSupabaseClient({ req, res })
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'
サーバサイドの処理でもAPI Routes
のような、明確にリクエストとレスポンスが存在する処理用のクライアント生成関数です。createServerComponentSupabaseClient({ headers, cookies })
と同じく、セキュリティの観点から積極的に活用した方が良さそうです。
createMiddlewareSupabaseClient({ req, res })
import { createMiddlewareSupabaseClient } from '@supabase/auth-helpers-nextjs'
ミドルウェア用のクライアント生成関数です。利用する理由については上記と同じなため割愛。この層で認証情報チェックして分岐したりできると、app/
が管理しやすくなりそうです。
まとめ
似たような関数が色々あってわかりにくいですが、面倒なCookie
やHeader
の検証も含めて自動的にやってくれるため、非常に便利なライブラリです。行レベルセキュリティ
などSupabaseの機能を最大限活用するのであれば、積極的に活用していきたいです。また、認証用のUIライブラリまで用意されているそうです。こちらについては別の記事が書こうかなと考えています。