👾

Next.js + next-auth + PrismaでDiscordの認証を作る

2025/01/05に公開

概要

Next.js + next-auth + PrismaでDiscordの認証を試したいと思います。

事前作業

Discord developer PortalでApplicationを作成し、OAuth2の画面で以下の値を取得・設定する。

Next.jsのセットアップ

お試しのため、全てNoで選択

npx create-next-app@latest --typescript

必要ライブラリのインストール

next-authprismaのインストール

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