Пошук уроків, статей та іншого контенту
Підключите Auth.js до Next.js і налаштуєте провайдери, адаптер та базову конфігурацію автентифікації.
Auth.js — бібліотека для автентифікації в JavaScript-застосунках. У Next.js вона дозволяє:
входити через OAuth-провайдерів, наприклад GitHub;
зберігати користувачів і пов’язані акаунти в базі даних;
отримувати поточну сесію на сервері;
виходити з акаунта;
захищати сторінки та серверні функції.
У Next.js використовується пакет next-auth, а конфігурація Auth.js зазвичай зберігається у файлі auth.ts у корені проєкту.
У цьому уроці ми налаштуємо:
GitHub як провайдер автентифікації.
Prisma як адаптер для збереження даних у SQLite.
API-маршрут Auth.js.
Вхід, вихід і читання сесії.
Для проєкту Next.js встановіть Auth.js, Prisma та адаптер Prisma:
npm install next-auth @auth/prisma-adapter @prisma/client
npm install --save-dev prismaІніціалізуйте Prisma з SQLite:
npx prisma init --datasource-provider sqliteПісля цього Prisma створить файл prisma/schema.prisma і файл .env.
У файлі .env вкажіть шлях до SQLite-бази:
DATABASE_URL="file:./dev.db"У prisma/schema.prisma додайте моделі, які потрібні Prisma-адаптеру Auth.js:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
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 {
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}Створіть таблиці в базі даних:
npx prisma migrate dev --name initДля роботи з Prisma створіть файл lib/prisma.ts:
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}Такий підхід не створює зайві екземпляри PrismaClient під час гарячого перезавантаження в режимі розробки.
Для входу через GitHub потрібні OAuth-дані застосунку:
Client ID;
Client Secret.
Під час створення GitHub OAuth App вкажіть callback URL:
http://localhost:3000/api/auth/callback/githubДодайте отримані значення у .env:
AUTH_SECRET="згенерований_секрет"
AUTH_GITHUB_ID="ідентифікатор_GitHub_застосунку"
AUTH_GITHUB_SECRET="секрет_GitHub_застосунку"AUTH_SECRET використовується Auth.js для підпису та шифрування даних сесії. Його значення не можна публікувати або передавати на клієнт.
Наприклад, секрет можна згенерувати командою:
openssl rand -base64 32Створіть у корені проєкту файл auth.ts:
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/lib/prisma";
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
GitHub,
],
session: {
strategy: "database",
},
});Розглянемо основні частини конфігурації:
GitHub — провайдер, через який користувач входить у застосунок;
PrismaAdapter(prisma) — адаптер, який зберігає користувачів, акаунти та сесії у базі даних;
session.strategy зі значенням "database" — зберігання сесій у базі даних;
handlers — обробники HTTP-запитів Auth.js;
auth — функція для отримання поточної сесії;
signIn і signOut — серверні функції для входу та виходу.
Auth.js автоматично прочитає AUTH_GITHUB_ID, AUTH_GITHUB_SECRET і AUTH_SECRET із змінних середовища.
Створіть файл:
app/api/auth/[...nextauth]/route.tsДодайте до нього:
import { handlers } from "@/auth";
export const { GET, POST } = handlers;Цей маршрут обробляє запити Auth.js, зокрема:
початок входу через провайдера;
callback після входу;
вихід із системи;
роботу із сесією.
Для GitHub callback-маршрут буде таким:
/api/auth/callback/githubСаме цей шлях потрібно вказати у налаштуваннях OAuth-застосунку GitHub.
Функції auth, signIn і signOut можна використовувати безпосередньо в Server Components.
Наприклад, файл app/page.tsx:
import { auth, signIn, signOut } from "@/auth";
export default async function HomePage() {
const session = await auth();
if (session?.user) {
return (
<main>
<h1>Вітаємо, {session.user.name ?? session.user.email}</h1>
{session.user.image && (
<img
src={session.user.image}
alt="Аватар користувача"
width={64}
height={64}
/>
)}
<form
action={async () => {
"use server";
await signOut();
}}
>
<button type="submit">Вийти</button>
</form>
</main>
);
}
return (
<main>
<h1>Вхід до застосунку</h1>
<form
action={async () => {
"use server";
await signIn("github");
}}
>
<button type="submit">Увійти через GitHub</button>
</form>
</main>
);
}Виклик auth() повертає сесію поточного користувача або null, якщо користувач не автентифікований.
Об’єкт сесії може містити:
{
user: {
name: string | null;
email: string | null;
image: string | null;
}
}Виклик signIn("github") перенаправляє користувача на GitHub. Після успішного входу GitHub повертає користувача до Next.js, а Auth.js створює запис користувача та сесію.
Виклик signOut() завершує поточну сесію.
Без адаптера Auth.js може працювати із сесіями без збереження користувача в базі даних. Адаптер додає постійне сховище для даних автентифікації.
Під час першого входу через GitHub Prisma-адаптер зберігає:
користувача в таблиці User;
зв’язок із GitHub у таблиці Account;
сесію в таблиці Session.
Повторний вхід через той самий GitHub-акаунт використовує вже наявний зв’язок у Account.
Важливо розрізняти:
користувача — запис у вашій системі;
акаунт провайдера — зв’язок користувача з GitHub;
сесію — поточний стан входу користувача.
Запустіть застосунок:
npm run devВідкрийте:
http://localhost:3000Після натискання «Увійти через GitHub» має відбутися така послідовність:
Next.js перенаправить вас на GitHub.
GitHub попросить підтвердити доступ.
GitHub поверне вас на callback URL.
Auth.js створить або знайде користувача.
Prisma збереже сесію в SQLite.
Головна сторінка покаже дані користувача.
Callback URL у GitHub має точно відповідати маршруту Auth.js:
http://localhost:3000/api/auth/callback/githubПомилки в протоколі, порту або шляху призводять до помилки OAuth.
Переконайтеся, що .env містить усі необхідні змінні:
AUTH_SECRET="..."
AUTH_GITHUB_ID="..."
AUTH_GITHUB_SECRET="..."
DATABASE_URL="file:./dev.db"Після зміни .env перезапустіть сервер розробки.
Якщо таблиці не створені, адаптер не зможе зберегти користувача або сесію. Виконайте:
npx prisma migrate dev --name initauth() у клієнтському компонентіФункція auth() використовується на сервері. Не імпортуйте її у компонент із директивою "use client".
Для базової конфігурації достатньо отримувати сесію в Server Component або серверній функції.
Не використовуйте AUTH_SECRET, AUTH_GITHUB_SECRET або інші секрети у змінних із префіксом NEXT_PUBLIC_. Такі значення не повинні бути доступні браузеру.
У цьому уроці ви:
встановили next-auth та Prisma-адаптер;
описали моделі Auth.js у Prisma;
створили GitHub OAuth-провайдера;
налаштували auth.ts;
підключили API-маршрут Auth.js;
реалізували вхід через GitHub;
реалізували вихід із системи;
отримали поточну сесію на сервері;
налаштували зберігання користувачів і сесій у базі даних.