SupabaseのAuth Helperを使うときの注意点(Next.js v13前提)

# SupabaseのAuth Helperを使うときの注意点
:::note warn
筆者もNext.js v13やSupabaseを利用し始めてから日が浅いため、一部未検証な部分があります。
:::

## Supabase公式の認証ヘルパーライブラリ
ベータではありますが、Supabase公式から[`Next.js`をはじめとする幾つかのフレームワーク用に認証のヘルパーライブラリ](https://supabase.com/docs/guides/auth/auth-helpers)が提供されています。`Next.js`では、`Next Auth`が認証管理のデファクトスタンダートであると思いますが、`Supabase Auth`の機能を活用するなら上記のヘルパーライブラリを用いるように示されています。

:::note info
[Next Authの公式ドキュメント](https://next-auth.js.org/adapters/supabase)から引用
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の接続クライアントが色々あって違いがわからない…
[公式のドキュメント](https://supabase.com/docs/guides/auth/auth-helpers/nextjs-server-components)を見ればわかるのですが、クライアント生成関数が複数存在します。使用する場面を間違えるとエラーはないのにビルドが通らなくなります。そのため、各関数の使い方には注意しなければなりません。

### `createClient(url, anon)`
```tsx
import { createClient } from '@supabase/supabase-js'
```
https://github.com/supabase/auth-helpers

この関数はヘルパーライブラリではなく、[`supabase-js`](https://github.com/supabase/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()`
```tsx
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
```

ブラウザで利用するクライアント生成関数です。これ経由で取得した認証情報とサーバ側の認証情報が同一か検証する方法が公式ドキュメントで紹介されています。SSRやSSGを考慮しないSPAであれば、これだけで問題ないと思います。

### `createServerComponentSupabaseClient({ headers, cookies })`
```tsx
import { createServerComponentSupabaseClient } from '@supabase/auth-helpers-nextjs'
```
`Reaxt Server Component`用のクライアント生成関数です。`Header`や`Cookie`からクライアントを生成してくれます。ユーザのセッションも引き継がれるため、`行レベルセキュリティ`を導入していれば、ユーザの権限外のデータベース操作は行えないはずです(**要検証**)。プログラマのミスで他ユーザにまで波及する操作を実装しても、実行時にエラーになるのでプログラムの安全性が向上します。`Server Component`が主体の`app`ディレクトリでは、積極的に利用した方が良さそうです。

### `createServerSupabaseClient({ req, res })`
```tsx
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'
```
サーバサイドの処理でも`API Routes`のような、明確にリクエストとレスポンスが存在する処理用のクライアント生成関数です。`createServerComponentSupabaseClient({ headers, cookies })`と同じく、セキュリティの観点から積極的に活用した方が良さそうです。

### `createMiddlewareSupabaseClient({ req, res })`
```tsx
import { createMiddlewareSupabaseClient } from '@supabase/auth-helpers-nextjs'
```

ミドルウェア用のクライアント生成関数です。利用する理由については上記と同じなため割愛。この層で認証情報チェックして分岐したりできると、`app/`が管理しやすくなりそうです。

## まとめ
似たような関数が色々あってわかりにくいですが、面倒な`Cookie`や`Header`の検証も含めて自動的にやってくれるため、非常に便利なライブラリです。`行レベルセキュリティ`などSupabaseの機能を最大限活用するのであれば、積極的に活用していきたいです。また、認証用のUIライブラリまで用意されているそうです。こちらについては別の記事が書こうかなと考えています。