📑
Next.js+NextAuthで認証情報をDBで管理する
前回、上記でGoogleのソーシャルログインする方法を試しました。現状はCookieで認証情報を保持しているだけで、サーバサイドでも認証情報を保持管理したいので、DBで管理できるようにします。
NextAuthではオプションでDBで管理する機能も備わっています。Adapterという機能になります。
対象バージョン
Next.js 15.1.7
NextAuth 5.0.0-beta.25
Prisma Client 6.4.1
PostgreSQL 16.4(AzureのDBaaS)
今回は prisma というORMを利用します。公式のマニュアルに沿って対応します。
インストール
必要なライブラリをインストールします
pnpm add @prisma/client @auth/prisma-adapter
pnpm add prisma --save-dev
初期設定
上記のコマンド実施後にPJのルートに prisma というフォルダと schema.prisma というファイルができます。
npx prisma init --datasource-provider postgresql
DBの接続情報を更新することと、認証に必要なテーブルの定義をNextAuthのマニュアルからコピペします。
schema.prisma
model user {
id String @id @default(cuid())
name String?
email String @unique
emailVerified DateTime?
image String?
accounts account[]
sessions session[]
authenticator Authenticator[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model account {
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([provider, providerAccountId])
}
model session {
sessionToken String @unique
userId String
expires DateTime
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model verificationToken {
identifier String
token String
expires DateTime
@@id([identifier, token])
}
model authenticator {
credentialID String @unique
userId String
providerAccountId String
credentialPublicKey String
counter Int
credentialDeviceType String
credentialBackedUp Boolean
transports String?
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([userId, credentialID])
}
DBのマイグレーション
DBに対して定義情報を元にテーブルが作成される。ORマップするプログラムの定義ファイルも作成する。
pnpm exec prisma migrate dev
pnpm exec prisma generate
認証の設定ファイル修正
ルートに prisma.ts というファイルを作成してライブラリを読み込むのとauth.tsを更新する。
prisma.ts
import { PrismaClient } from "@prisma/client"
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
認証の設定ファイルも修正する
auth.ts
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { prisma } from "@/prisma"
import Google from "next-auth/providers/google"
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [Google],
})
実際に動かす
pnpm run dev
http://localhost:3000 にアクセスしてログイン試行すると
想定通りログインできました。
DBを見てみるとユーザーなどテーブルにレコードができてます。長いのでいくつかのカラムをピックアップしてます。
itsumo=> select * from public.user;
id| name | email |
XX| kai kusakari | kai.kusakari@gmail.com |
itsumo=> select * from public.session;
sessionToken. | userId |
<sessionToken>| XX |
画面上からログアウトするとsessionテーブルからレコードが消えました。
userテーブルにはGoogleからOAuthで受け取ったuseridが入っています。自身のWEBアプリでは独自のIDを割り振って、受け取ったuseridとマップするような仕組みを実装していけたらと思います。
(Google以外の認証手段を増やした時にuseridが重複する可能性など制限があるためです)
今回で本人確認など認証部分を作成できたため、次回は認証情報を使って、登録機能や、自身が登録した内容の一覧機能を実装して試してみます。
Discussion