Better Auth
10分 9秒
Better Auth とは
Better Auth は、認証を簡単に設定できる次世代の認証ライブラリです。
- 認証の設定を定義
- 認証に必要な ORMスキーマを生成(マイグレーション)
- 動作
となります。スキーマも一般的な内容であるためロックインを気にせず導入できます。
インストール
Base URL 判定
(推奨)Better Auth はアプリが動作するURLを知る必要がありますが、Vercelの場合はプレビュー環境ごとにURLが生成され、この判定が複雑になるため既存のヘルパーを導入します。
マニュアルで作成する場合
インスタンスの作成
Drizzle を使う想定です。サーバー用のインスタンスとクライアント用のインスタンスを用意します。サーバー用のインスタンスは Better Auth の設定も兼ねており、ORMスキーマの生成に影響します。
今回は匿名ログインをベースに進めます。
Better Auth がはじめての場合や開発初期の場合、匿名ログインを有効にすることをお勧めします。匿名ログインを使うとメールアドレスやSNSアカウントを使わずにログインできます。
サーバー用のインスタンス
サーバーサイドから認証機能にアクセスする場合は、サーバー用のインスタンスを作成します。
クライアント用のインスタンス
"use client" を使うクライアントコンポーネントから認証機能にアクセスする場合は、クライアント用のインスタンスを作成します。
ルートハンドラー
Better Auth を動作させるために、ルートハンドラーを作成します。
Proxy の設定
認証状態に応じてリダイレクトする場合、Proxy を設定します。たとえばログインしていないユーザーをログインページにリダイレクトする場合、以下のように設定します。
ここで行っているのは画面やデータの保護ではなく、あくまで「ログインしてないユーザーをログイン画面に飛ばす」というシンプルなリダイレクト処理です。データの保護は別途データ取得関数で行なってください。
くわしく
ここでは getSessionCookie を使って Cookie の内容でログイン状態を判断していますが、Cookie は誰でも書き換えることができます。データベースにログイン状態を問い合わせないので高速ですが、信頼性は低くなります。
ただし基本的には画面に必要なデータを取得するタイミングでサーバーサイドの検証を行うため問題ありません。たとえCookieを偽装して画面にアクセスしても、肝心のデータ取得が失敗するので情報漏洩にはなりません。
データベースの更新
認証機能を動作させるために、データベースにテーブルを追加する必要があります。
スキーマの生成
ORM 用のスキーマを生成します。--output で出力先を指定します。実際のスキーマの場所を指定してください。
lib/auth.ts に応じてデータベースも更新する必要があるので、その都度上記コマンドを実行してスキーマを再生成します。この観点から、生成された auth.ts を直接編集するのはお勧めしません。
今後のためにスクリプトを用意しておくと便利です。
マイグレーション
スキーマができたら ORM の設定に生成されたスキーマを加え、マイグレーションを実行します。
データの保護
画面のリダイレクトは proxy.ts で Cookie を参照して楽観的に行っていますが、データの保護はデータ通信関数で行います。
保護用のヘルパー関数
getSession と currentSession を作成します。
getSession- セッションの有無を確認する場合に使用currentSession- セッションの存在を担保する場合に使用
redirect を使うとその時点で処理が強制終了するため、currentSession を挟むことでログインしていないユーザーの処理を中断できます。
データベースとの通信関数では基本的に currentSession を使ってログイン状態を担保しつつログイン中のユーザーを特定し、そのユーザーのIDに基づいてデータベースを操作します。
安全なデータの取得
安全なデータの更新
個人の特定はサーバーサイドで行う
たとえば自分のプロフィールを更新する場合、自分が誰であるかは必ずサーバーサイドで特定します。
ログアウト
サーバーアクションと refresh を使ってログアウトおよび即時反映ができます。
ボタンコンポーネント
ログイン状態に応じたUIの出しわけ
ログイン不要でみれて良い画面の場合、getSession を使ってログイン状態を確認します。 currentSession を使うとログインしていない場合リダイレクトされてしまいます。