👾
Next.js + next-auth + PrismaでDiscordの認証を作る
概要
Next.js + next-auth + PrismaでDiscordの認証を試したいと思います。
事前作業
Discord developer PortalでApplicationを作成し、OAuth2の画面で以下の値を取得・設定する。
- CLIENT ID
- CLIENT SECRET
- Redirects:http://localhost:3000/api/auth/callback/discord
Next.jsのセットアップ
お試しのため、全てNoで選択
npx create-next-app@latest --typescript
必要ライブラリのインストール
next-auth
とprisma
のインストール
npm install next-auth prisma @prisma/client @next-auth/prisma-adapter
環境ファイルの作成
// .env
DATABASE_URL="file:./dev.db"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET=""
DISCORD_CLIENT_ID=""
DISCORD_CLIENT_SECRET=""
NEXTAUTH_SECRET
は以下のコマンドで生成する。
openssl rand -base64 32
Prismaの設定・マイグレーション
Prismaの初期化
npx prisma init
スキーマファイルの作成
// prisma/schema.prisma
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model Account {
id String @id @default(cuid())
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?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
公式サイト:https://authjs.dev/getting-started/adapters/prisma
マイグレーション実施
npx prisma migrate dev --name init
next-auth の設定
// pages/api/auth/[...nextauth].ts
import NextAuth, { NextAuthOptions } from "next-auth"
import DiscordProvider from "next-auth/providers/discord"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
export const authOptions: NextAuthOptions = {
adapter: PrismaAdapter(prisma),
providers: [
DiscordProvider({
clientId: process.env.DISCORD_CLIENT_ID ?? "",
clientSecret: process.env.DISCORD_CLIENT_SECRET ?? "",
}),
],
}
export default NextAuth(authOptions)
ログイン画面作成
// pages/index.tsx
import { signIn, signOut, useSession } from "next-auth/react"
export default function Home() {
const { data: session } = useSession()
if (!session) {
return (
<div>
<h1>Not logged in</h1>
<button onClick={() => signIn("discord")}>Sign in with Discord</button>
</div>
)
}
return (
<div>
<h1>Logged in as {session.user?.name}</h1>
<button onClick={() => signOut()}>Sign out</button>
</div>
)
}
起動
以下のコマンドで起動する。起動後、http://localhost:3000にアクセスする。
npm run dev
無事ログインできているようです。
Discussion