Пошук уроків, статей та іншого контенту
Додасте OAuth-провайдерів і реалізуєте вхід через Google, GitHub або інші соціальні мережі за допомогою Auth.js.
OAuth дає змогу користувачеві увійти у ваш застосунок через уже наявний обліковий запис Google, GitHub або іншого провайдера. Ваш застосунок не отримує пароль користувача: провайдер підтверджує особу й повертає застосунку обмежений набір даних та OAuth-токени.
Auth.js інтегрує цей процес із Next.js:
користувач натискає кнопку входу;
Auth.js перенаправляє його до OAuth-провайдера;
користувач надає дозвіл;
провайдер перенаправляє користувача назад на callback URL;
Auth.js створює сесію;
сервер Next.js може отримати дані поточного користувача.
Встановіть пакет:
npm install next-authДля Auth.js потрібен секретний ключ. Він використовується для підпису та шифрування даних сесії.
Згенерувати ключ у macOS або Linux можна так:
openssl rand -base64 32Створіть файл .env.local:
AUTH_SECRET=ваш_довгий_випадковий_секретНе додавайте .env.local до Git-репозиторію. У стандартному проєкті Next.js цей файл уже зазвичай доданий до .gitignore.
Перед налаштуванням Auth.js потрібно створити OAuth-застосунок у кожного провайдера.
У налаштуваннях Google OAuth-застосунку вкажіть:
дозволені origin-и:
http://localhost:3000
callback URL:
http://localhost:3000/api/auth/callback/google
Для production використовуйте точний домен застосунку, наприклад:
https://example.com/api/auth/callback/googleДодайте отримані значення у .env.local:
AUTH_GOOGLE_ID=ідентифікатор_застосунку_google
AUTH_GOOGLE_SECRET=секрет_застосунку_googleУ налаштуваннях GitHub OAuth App вкажіть callback URL:
http://localhost:3000/api/auth/callback/githubЗмінні середовища:
AUTH_GITHUB_ID=ідентифікатор_застосунку_github
AUTH_GITHUB_SECRET=секрет_застосунку_githubCallback URL залежить від ідентифікатора провайдера. Для Google це google, для GitHub — github.
Створіть файл auth.ts у корені проєкту:
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import GitHub from "next-auth/providers/github";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
Google,
GitHub,
],
});Провайдери Google і GitHub автоматично використовують змінні:
AUTH_GOOGLE_ID;
AUTH_GOOGLE_SECRET;
AUTH_GITHUB_ID;
AUTH_GITHUB_SECRET.
Якщо змінні для певного провайдера не задані, не додавайте цей провайдер до конфігурації. Наприклад, для входу лише через Google:
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [Google],
});Створіть файл:
app/api/auth/[...nextauth]/route.tsДодайте до нього:
import { handlers } from "@/auth";
export const { GET, POST } = handlers;Цей route обробляє:
початок OAuth-авторизації;
callback від провайдера;
вихід із системи;
операції із сесією.
Шлях app/api/auth/[...nextauth]/route.ts важливий. Якщо route має іншу структуру, OAuth callback не працюватиме за очікуваною адресою.
Створіть сторінку app/login/page.tsx:
import { signIn } from "@/auth";
export default function LoginPage() {
async function loginWithGoogle() {
"use server";
await signIn("google", {
redirectTo: "/",
});
}
async function loginWithGitHub() {
"use server";
await signIn("github", {
redirectTo: "/",
});
}
return (
<main>
<h1>Вхід</h1>
<form action={loginWithGoogle}>
<button type="submit">Увійти через Google</button>
</form>
<form action={loginWithGitHub}>
<button type="submit">Увійти через GitHub</button>
</form>
</main>
);
}signIn імпортовано з локального файлу auth.ts. Це серверна функція, тому вона може використовуватися у Server Action.
Після виклику signIn("google") Auth.js перенаправить користувача на Google. Після успішної авторизації користувач повернеться до застосунку, а Auth.js перенаправить його на шлях, указаний у redirectTo.
Ідентифікатори провайдерів:
google
githubДля інших провайдерів потрібно використовувати їхні ідентифікатори, визначені відповідним Auth.js provider.
Функція auth() призначена для отримання сесії на сервері. Наприклад, змініть app/page.tsx:
import Link from "next/link";
import { auth, signOut } from "@/auth";
export default async function HomePage() {
const session = await auth();
if (!session?.user) {
return (
<main>
<h1>Головна сторінка</h1>
<p>Ви ще не увійшли до системи.</p>
<Link href="/login">Увійти</Link>
</main>
);
}
async function logout() {
"use server";
await signOut({
redirectTo: "/",
});
}
return (
<main>
<h1>Вітаємо!</h1>
<p>
Користувач: {session.user.name ?? "Без імені"}
</p>
<p>
Email: {session.user.email ?? "Email відсутній"}
</p>
<form action={logout}>
<button type="submit">Вийти</button>
</form>
</main>
);
}auth() повертає об’єкт сесії або null, якщо користувач не автентифікований.
Типова структура сесії має такий вигляд:
{
user: {
name: "Ada Lovelace",
email: "ada@example.com",
image: "https://..."
},
expires: "..."
}Окремі поля можуть бути відсутніми, тому в інтерфейсі варто передбачати значення за замовчуванням.
Перевірку сесії можна виконати безпосередньо в Server Component. Якщо користувач не ввійшов, його можна перенаправити на сторінку входу:
import { auth } from "@/auth";
import { redirect } from "next/navigation";
export default async function DashboardPage() {
const session = await auth();
if (!session?.user) {
redirect("/login");
}
return (
<main>
<h1>Панель керування</h1>
<p>Ця сторінка доступна лише автентифікованим користувачам.</p>
<p>Ваш email: {session.user.email}</p>
</main>
);
}Перевірка виконується на сервері до відображення сторінки. Це важливо: приховати кнопку в інтерфейсі недостатньо для захисту даних або операцій.
Auth.js має окремі provider-модулі для багатьох OAuth-сервісів. Загальний принцип однаковий:
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import GitHub from "next-auth/providers/github";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
Google,
GitHub,
],
});Для кожного провайдера потрібно:
імпортувати його provider;
додати provider до масиву providers;
створити OAuth-застосунок у відповідному сервісі;
додати Client ID і Client Secret до змінних середовища;
додати правильний callback URL;
передати правильний ідентифікатор у signIn.
Наприклад, якщо провайдер має ідентифікатор github, кнопка входу викликає:
await signIn("github");Запустіть застосунок:
npm run devВідкрийте сторінку:
http://localhost:3000/loginПеревірте такий сценарій:
натисніть кнопку Google або GitHub;
завершіть авторизацію у провайдера;
переконайтеся, що відбулося перенаправлення на головну сторінку;
перевірте ім’я та email у сесії;
натисніть «Вийти»;
переконайтеся, що захищена сторінка більше недоступна.
Якщо ви змінюєте змінні у .env.local, перезапустіть сервер розробки.
У production потрібно:
додати AUTH_SECRET у змінні середовища хостингу;
додати Client ID і Client Secret OAuth-провайдерів;
додати production callback URL у налаштуваннях кожного провайдера;
переконатися, що callback URL точно збігається з URL застосунку.
Наприклад, для домену https://example.com callback URL буде:
https://example.com/api/auth/callback/googleНе використовуйте callback URL із localhost для production-конфігурації.
Callback URL має збігатися повністю:
протокол http або https;
домен;
порт;
шлях;
ідентифікатор провайдера.
Наприклад, http://localhost:3000/api/auth/callback/google і http://127.0.0.1:3000/api/auth/callback/google — різні адреси.
Перевірте, що в .env.local є:
AUTH_SECRET=...
AUTH_GOOGLE_ID=...
AUTH_GOOGLE_SECRET=...Назви змінних мають бути написані точно. Після їх додавання перезапустіть Next.js.
Не додавайте OAuth Client Secret до змінних із префіксом NEXT_PUBLIC_. Такі змінні доступні браузеру.
Правильно:
AUTH_GOOGLE_SECRET=секретНеправильно:
NEXT_PUBLIC_GOOGLE_SECRET=секретauth() у Client Componentauth() призначена для серверного використання. Не імпортуйте її у компонент із директивою "use client".
Для цього уроку достатньо отримувати сесію у Server Component. Це також дозволяє перевіряти доступ до сторінки на сервері.
Недостатньо створити OAuth-застосунок і додати змінні середовища. Провайдер також має бути у масиві providers:
providers: [Google, GitHub]Дані сесії використовуються для відображення користувача, але доступ до захищених операцій потрібно перевіряти на сервері. Перед виконанням зміни даних знову перевіряйте auth() у відповідному Server Action або route handler.
OAuth дозволяє входити через зовнішнього провайдера без зберігання пароля у вашому застосунку.
Auth.js підключає OAuth-провайдерів через providers.
Для кожного провайдера потрібні Client ID, Client Secret і правильний callback URL.
Route app/api/auth/[...nextauth]/route.ts обробляє OAuth-запити.
signIn("google") або signIn("github") запускає авторизацію.
auth() повертає поточну серверну сесію.
Захищати сторінки потрібно перевіркою сесії на сервері.
OAuth-секрети та AUTH_SECRET не можна публікувати або передавати у клієнтський код.