要件
- Googleアカウントでログイン・ログアウトする
- ログイン状態に応じて画面の要素を出し分ける・リダイレクトさせる (認可)
- ログインしたユーザーとセッション情報をDBに保存する
環境・技術
- Next.js 14 (App Router)
- Drizzle ORM (PostgreSQL)
実装
0. ORMの導入
下記記事のようにDrizzle ORMの設定が完了している前提で進める。
【Next.js】Drizzle ORMを導入してマイグレーションするまで
1. GCPの設定
まずクライアントIDの作成 | Google Cloudに沿ってGoogleのOAuthクライアントIDとシークレットキーを取得する。
2. 環境変数を設定
先程GCPで取得したクライアントIDとシークレットを環境変数に設定する。
NEXTAUTH_SECRET
はメール認証トークンのハッシュ化とJWTの暗号化に必要なもので、上記のコマンドで生成できる。
3. ライブラリのインストール
4. providerとadapterを設定
認証にまつわる設定を実装する。
- 今回はGoogle認証のみを利用するので
providers
にGoogleProvider
を指定
adapter
にDrizzleAdapter
を指定するだけで、Drizzle ORMを介して対象のテーブルに読み書きしてくれる
以降はここでexportした{ handlers, auth, signOut }
を利用していく。
5. 認証用のAPI Routeを作成
6. テーブルを作成
6-1. スキーマを宣言
Drizzle ORMを介して対象のテーブルに読み書きするためには、adapter側で想定しているテーブル・カラムを用意する必要がある。
そこで@auth/drizzle-adapterの公式ドキュメントに記載されている通りにスキーマを宣言する (一部カラムの型や制約はカスタムしている) 。
6-2. マイグレーション
7. プロフィール画面を実装
ログイン中のアカウント情報を表示する/me
を実装する。
src/infra/auth/index.ts
でエクスポートしたauth()
でセッション情報を取得し、ユーザー情報を表示
- 「logout」ボタンを押下するとServer Action内で
signOut()
を呼ぶ
- 未ログインであればログインページにリダイレクト
8. 動作確認
/api/auth/signin
にアクセスするとログインボタンが表示された。
押下するとGoogleアカウントのログイン画面が表示されるのでアカウントを選択。
/me
にアクセスすると、対象ユーザーの情報が表示された。
npm run db:preview
でDrizzle Studioを起動し、User
・Account
・Session
テーブルを参照してみるとレコードも挿入されていることが確認できる。
また「logout」ボタンを押下し/me
にアクセスするとトップページにリダイレクトされ、Session
テーブルのレコードも削除された。
発展
ミドルウェアで認可する
今回の/me
のようなページのみを保護対象にしたいので、ミドルウェアを用いて認可 (ガード) 機能を実装する。
ミドルウェアの設定として認証周りのRouteを対象から除外し、あとはauth
をdefault exportするだけ。
未ログインで/me
にアクセスすると/api/auth/signin
にリダイレクトされるようになった。
session.userに任意のプロパティを含める
デフォルトだとsession.user
オブジェクトにidが含まれないが、session()
をオーバーライドして含めることも可能。
またSession
の型を拡張してidを含めることで型も補完される。
12