Пошук уроків, статей та іншого контенту
Порівняєте authentication та authorization і визначите, які завдання вирішує кожен із цих процесів у застосунку.
Вебзастосунок має відповісти на два різні запитання:
Authentication — хто ви?
Authorization — що вам дозволено?
Українською ці поняття часто перекладають так:
автентифікація — перевірка особи;
авторизація — перевірка прав доступу.
Ці процеси пов’язані, але не є взаємозамінними.
Authentication підтверджує, що користувач є саме тією особою, за яку себе видає.
Приклади:
введення електронної пошти та пароля;
вхід через Google або GitHub;
перевірка одноразового коду;
перевірка дійсності сесії або токена.
Після успішної автентифікації застосунок може отримати дані користувача, наприклад:
{
id: "user-123",
name: "Olena",
role: "editor"
}До автентифікації застосунок не знає, хто саме робить запит.
Охоронець перевіряє паспорт відвідувача. Це автентифікація: охоронець встановлює особу людини.
Authorization визначає, які дії може виконувати вже відомий користувач.
Приклади:
звичайний користувач може переглядати власний профіль;
редактор може редагувати статті;
адміністратор може видаляти користувачів;
користувач може переглядати лише власні замовлення.
Для авторизації застосунок використовує дані, отримані під час автентифікації: ідентифікатор користувача, роль, дозволи та інші атрибути.
Охоронець перевіряє перепустку й визначає, до яких кімнат можна зайти. Це авторизація: особу вже встановлено, тепер перевіряються її права.
Зазвичай процес виглядає так:
Користувач надсилає дані для входу.
Застосунок перевіряє ці дані — це автентифікація.
Застосунок створює сесію або видає токен.
Користувач надсилає сесію чи токен у наступних запитах.
Застосунок визначає користувача.
Застосунок перевіряє, чи має цей користувач право виконати дію — це авторизація.
Застосунок повертає результат або відмовляє в доступі.
Важливо: авторизація має сенс лише після автентифікації. Неможливо надійно визначити права користувача, якщо застосунок не знає, хто він.
У Next.js перевірки можна виконувати, наприклад, у Route Handler. Нижче наведено спрощений приклад для App Router.
Файл app/api/admin/report/route.js:
import { NextResponse } from "next/server";
// Демонстраційне сховище сесій.
// У реальному застосунку сесії зберігають у базі даних
// або перевіряють підписаний токен.
const sessions = {
"session-alice": {
id: "user-1",
name: "Alice",
role: "admin",
},
"session-oleh": {
id: "user-2",
name: "Oleh",
role: "user",
},
};
export async function GET(request) {
const sessionId = request.cookies.get("session")?.value;
const currentUser = sessions[sessionId];
// Authentication: визначаємо, хто виконує запит.
if (!currentUser) {
return NextResponse.json(
{ error: "Потрібно увійти в систему" },
{ status: 401 },
);
}
// Authorization: перевіряємо право доступу.
if (currentUser.role !== "admin") {
return NextResponse.json(
{ error: "Недостатньо прав" },
{ status: 403 },
);
}
return NextResponse.json({
message: "Звіт доступний",
requestedBy: currentUser.name,
});
}У цьому прикладі є два окремі етапи:
const currentUser = sessions[sessionId];Це автентифікація. Застосунок дістає ідентифікатор сесії з cookie та визначає користувача.
if (currentUser.role !== "admin") {
// ...
}Це авторизація. Застосунок перевіряє, чи має відомий користувач роль адміністратора.
Сховище
sessionsу прикладі потрібне лише для пояснення. Реальний застосунок не повинен зберігати всі сесії в коді.
Для розділення цих ситуацій часто використовують різні HTTP-коди:
401 UnauthorizedЗапит не містить дійсної інформації для автентифікації.
Причини:
користувач не ввійшов у систему;
cookie сесії відсутня;
токен недійсний або прострочений.
У прикладі це відбувається, коли currentUser не знайдено.
403 ForbiddenКористувач автентифікований, але не має потрібних прав.
Наприклад:
користувач увійшов у систему;
його сесія дійсна;
але його роль не дозволяє переглядати адміністративний звіт.
У прикладі адміністратор отримує доступ, а користувач із роллю user — відповідь 403.
| Authentication | Authorization | |---|---| | Визначає особу користувача | Визначає дозволені дії | | Відповідає на питання «Хто це?» | Відповідає на питання «Що йому можна?» | | Перевіряє пароль, сесію або токен | Перевіряє роль, дозвіл або власність ресурсу | | Відбувається перед перевіркою прав | Виконується після визначення користувача | | Помилка часто означає 401 | Помилка часто означає 403 |
Авторизація не завжди обмежується роллю. Потрібно також перевіряти, чи має користувач доступ саме до запитаного ресурсу.
Наприклад, користувач може переглядати власний профіль, але не профіль іншої людини.
function canViewProfile(currentUser, profileId) {
return currentUser.id === profileId || currentUser.role === "admin";
}
const currentUser = {
id: "user-1",
role: "user",
};
console.log(canViewProfile(currentUser, "user-1")); // true
console.log(canViewProfile(currentUser, "user-2")); // falseТут користувач автентифікований, але авторизація дозволяє йому переглядати лише профіль із власним ідентифікатором.
Перевірку доступу потрібно виконувати на сервері — у місці, де захищені дані або дія справді доступні:
у Route Handler;
у серверній функції;
під час обробки серверної дії;
у серверному компоненті перед отриманням захищених даних.
Перевірка лише в інтерфейсі не захищає дані. Наприклад, приховування кнопки для звичайного користувача не заважає йому вручну надіслати HTTP-запит.
Неправильний підхід:
// Така перевірка лише приховує кнопку в інтерфейсі.
if (user.role === "admin") {
return <button>Видалити користувача</button>;
}Кнопку можна приховати для зручності, але сервер також має перевірити роль під час самого запиту на видалення.
Правильний принцип:
Клієнтський інтерфейс може покращити взаємодію, але остаточне рішення про доступ завжди приймає сервер.
Для кожного захищеного запиту поставте два запитання:
Чи вдалося визначити користувача?
Чи дозволено цьому користувачу виконати дію?
Наприклад, для адміністративного звіту:
Немає сесії
→ користувач невідомий
→ 401
Є дійсна сесія, але роль user
→ користувач відомий, прав недостатньо
→ 403
Є дійсна сесія і роль admin
→ доступ дозволено
→ 200Факт успішного входу не означає, що користувач має доступ до всіх функцій.
Код браузера можна змінити або обійти. Серверна перевірка є обов’язковою.
Cookie може містити ідентифікатор сесії, але сервер має перевірити, чи сесія дійсна та якому користувачу вона належить.
Відсутність автентифікації та відсутність дозволу — різні випадки. Їх потрібно розрізняти в логіці застосунку.
Навіть адміністраторські ролі не завжди відповідають усім правилам доступу. Іноді потрібно перевірити власника ресурсу, статус об’єкта або конкретний дозвіл.
Authentication перевіряє особу користувача.
Authorization перевіряє права вже відомого користувача.
Автентифікація відповідає на питання «Хто ви?».
Авторизація відповідає на питання «Що вам дозволено?».
401 зазвичай означає, що користувач не автентифікований.
403 означає, що користувач автентифікований, але не має потрібних прав.
У Next.js перевірки доступу потрібно виконувати на сервері.
Приховування елементів інтерфейсу не замінює серверну авторизацію.