Аутентификация и авторизация

8 / 21
25 мин чтения
Введение
О чём говорим

В прошлой части мы разбирали формы и валидацию — то есть как данные попадают в приложение и как вы держите вход аккуратным.

Теперь следующий “взрослый” слой: кто вообще делает запрос и имеет ли он право сделать то, что просит.

Важное различие терминов (и это место, где чаще всего путаются новички):

  • Аутентификация (authentication): “Кто ты?” — установить личность (логин/пароль, сессия, токен, SSO).
  • Авторизация (authorization): “Можно ли тебе это?” — проверить права в конкретном контексте (роль, группа, владелец записи, права на раздел и т.д.).

В этой части разберём:

  • как Laravel даёт “правильный путь” через Breeze/Jetstream/Fortify + middleware + policies,
  • как в Битриксе устроены пользователи (CUser, UserTable, модуль main) и модель прав (группы/роли/операции),
  • чем отличается сессия от токена (и почему “сделаю JWT и всё” — не всегда лучший план),
  • и как подключается OAuth/соцлогин в обоих подходах.

Аутентификация: сессии, токены и “что считать логином”

Что вы выбираете на самом деле

Когда вы говорите “добавить логин”, вы на самом деле выбираете три вещи:

  1. Механизм: сессия (cookie) или токен (API).
  2. Провайдера личности: локальная база пользователей или внешний SSO/OAuth.
  3. Сценарии безопасности: 2FA, ограничения по устройствам, rate limiting, восстановление пароля, подтверждение email.
💡 Практическая мысль

В 2026 большинство проектов живут в гибриде:

  • браузерная часть — сессии (удобнее, безопаснее по умолчанию),
  • API/интеграции — токены (Sanctum/Passport/JWT/REST OAuth).

Laravel: Breeze, Jetstream, Fortify — что выбрать и зачем

В Laravel аутентификация — это “собранный путь”: вы берёте пакет‑скелет и дальше наращиваете функциональность.

Breeze: быстрый старт “без магии”

Laravel Breeze — это лёгкий scaffolding:

  • страницы логина/регистрации,
  • восстановление пароля,
  • подтверждение email (если включите),
  • и стандартные контроллеры/маршруты.

Плюс Breeze в том, что он обычно остаётся понятным для Junior’а: минимум “платформенной магии”, максимум читабельных файлов.

Jetstream: “комбайн” для продуктовых кейсов

Jetstream берут, когда нужно больше “из коробки”:

  • профили,
  • 2FA,
  • (опционально) команды/тенанты,
  • готовый UI‑слой под выбранный стек.

Минус — выше порог входа: больше кода, больше концепций.

Fortify: когда UI ваш, а логика — стандартная

Fortify — это “headless” слой аутентификации: маршруты/экшены/правила, но без готовых страниц (логин, регистрация и т.п.).

Он удобен, когда вы хотите:

  • оставить стандартную механику (логин/логаут, reset password, email verification, 2FA),
  • но сверстать и построить UX сами (свои формы, свои страницы, свой фронтенд: Blade/Inertia/SPA).

Важно не путать: Fortify не заменяет токены для API. Если вам нужны API‑токены/доступы — это обычно Sanctum/Passport, а Fortify — про “как логиниться” и “как живёт сессия/учётка”.

📁 Опорные доки Authentication, Starter Kits, Fortify

Laravel: сессии как дефолт (и почему это хорошо)

Middleware auth как базовая граница

Самая важная привычка в Laravel: доступ к “личным” страницам закрывается на уровне маршрутов:

        use Illuminate\Support\Facades\Route;

Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', fn () => view('dashboard'));
});

    

Так вы не размазываете if (!Auth::check()) по контроллерам и шаблонам.

Логин “вручную” (чтобы понимать, как это работает)

Даже если вы используете Breeze, полезно один раз увидеть базовую механику:

        use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

public function login(Request $request)
{
    $credentials = $request->validate([
        'email' => ['required', 'email'],
        'password' => ['required'],
    ]);

    if (Auth::attempt($credentials, remember: true)) {
        $request->session()->regenerate();
        return redirect()->intended('/dashboard');
    }

    return back()->withErrors([
        'email' => 'Неверный email или пароль.',
    ])->onlyInput('email');
}

    

Три ключевых детали:

  • Auth::attempt() — проверка пары email/password и вход в сессию.
  • session()->regenerate() — защита от фиксации сессии.
  • intended() — возвращает пользователя туда, куда он хотел попасть до логина.

Laravel: токены для API (Sanctum/Passport) — не путайте с “логином на сайте”

Если у вас есть API, чаще всего вы выбираете один из двух путей:

  • Sanctum — хороший дефолт для “токенов для пользователей” и SPA (простая модель personal access tokens + cookie‑режим для SPA).
  • Passport — OAuth2‑сервер внутри Laravel (сильнее, но тяжелее).

Минимальный пример “персонального токена” (идея):

        use Illuminate\Http\Request;

public function token(Request $request): array
{
    $user = $request->user();
    $token = $user->createToken('api')->plainTextToken;

    return ['token' => $token];
}

    
📁 Опорные доки Sanctum, Passport
💡 Практическая мысль
Не внедряйте JWT “потому что модно”. Для браузерной части cookie+сессия часто безопаснее и проще в сопровождении.

Laravel: OAuth и социальный логин (Socialite)

В Laravel “соцлогин” чаще всего реализуют через Socialite:

  • редирект на провайдера,
  • callback,
  • создание/связывание пользователя.

Схема (упрощённо):

        use Laravel\Socialite\Facades\Socialite;

public function redirectToGoogle()
{
    return Socialite::driver('google')->redirect();
}

public function handleGoogleCallback()
{
    $socialUser = Socialite::driver('google')->user();

    // Здесь: найти/создать пользователя по provider_id/email и залогинить.
}

    
📁 Опорные доки Socialite

Bitrix: пользователи и аутентификация (классика через CUser и “по‑D7” через Engine)

В Битриксе аутентификация — это не “подключаем пакет”, а функция платформы:

  • пользователи хранятся в таблицах ядра,
  • права и группы — тоже часть ядра,
  • формы логина/регистрации часто подключаются как готовые компоненты/страницы,
  • и многое “ожидается” системой (сессия, sessid, механика авторизации).

Вариант A (классика): $USER/CUser — то, что вы чаще увидите в проектах

Базовые проверки: авторизован ли пользователь

Самая распространённая проверка в сайтах Битрикса:

        global $USER;

if (!$USER->IsAuthorized()) {
    LocalRedirect('/auth/');
}

    

CSRF‑барьер в форме: sessid

Если вы обрабатываете POST на сайте, у вас почти всегда есть пара:

  • в форме: bitrix_sessid_post()
  • в обработке: check_bitrix_sessid()

Это тот же смысловой слой, что @csrf в Laravel.

Вход/выход: как понимать “сессию в Битриксе”

В классическом сценарии Битрикс использует сессионную модель: пользователь “вошёл” — дальше вы проверяете доступ через $USER и права.

💡 Практическая мысль
Для “витринных” сайтов это удобно, но если вы делаете внешний API, вам нужно заранее договориться о модели токенов (или использовать штатный REST/OAuth‑контур под интеграции).
📁 Опорные доки (полезно держать рядом) Пользователи, Защита сессии (sessid)

Вариант B (D7‑подход): CurrentUser, UserTable, D7‑контроллеры и action filters

Если вы “топите за D7”, удобно отталкиваться от двух вещей:

  • текущий пользователь как объект: \Bitrix\Main\Engine\CurrentUser::get(),
  • обработчики как контроллеры: \Bitrix\Main\Engine\Controller + ActionFilter\* (практический аналог middleware).

Текущий пользователь без global $USER

        use Bitrix\Main\Engine\CurrentUser;

$currentUser = CurrentUser::get();
$userId = (int)$currentUser->getId();

if ($userId <= 0) {
    LocalRedirect('/auth/');
}

    

Тут нет отдельного isAuthorized(): самый простой критерий — есть ли ID.

Получить данные пользователя “по‑D7” (ORM)

        use Bitrix\Main\UserTable;

$user = UserTable::getById($userId)->fetch();

// $user['LOGIN'], $user['EMAIL'], $user['NAME'], ...

    

Защитить endpoint/экшен через action filters (D7‑контроллер)

Пример контроллера, где доступ к действию требует аутентификации и правильного HTTP‑метода:

        <?php

use Bitrix\Main\Engine\ActionFilter;
use Bitrix\Main\Engine\Controller;
use Bitrix\Main\UserTable;

final class ProfileController extends Controller
{
    public function configureActions(): array
    {
        return [
            'me' => [
                'prefilters' => [
                    new ActionFilter\Authentication(),
                    new ActionFilter\HttpMethod([ActionFilter\HttpMethod::METHOD_GET]),
                ],
            ],
        ];
    }

    public function meAction(): array
    {
        $userId = (int)$this->getCurrentUser()->getId();
        $user = UserTable::getById($userId)->fetch();

        return [
            'id' => $userId,
            'login' => $user['LOGIN'] ?? null,
            'email' => $user['EMAIL'] ?? null,
        ];
    }
}

    

Смысл: проверка “вошёл или нет” делается до выполнения action — ровно как в Laravel через middleware.

Bitrix: токены/интеграции и OAuth (реальность проектов)

У Битрикса сильная сторона — экосистема интеграций:

  • есть штатный REST‑слой для интеграций,
  • часто есть OAuth‑сценарии (особенно когда речь про приложения/внешние системы),
  • и “права приложения” живут отдельно от “прав пользователя на сайте”.

Рекомендация “по‑взрослому”: не пытаться прикрутить один универсальный токен для всего.

Типовое разделение:

  • сайт/личный кабинет — через сессии и обычного пользователя,
  • внешние интеграции — через REST/OAuth‑механику и отдельные ключи/клиенты,
  • внутренний сервис‑к‑сервису — через сервисные учётки и ограниченные права (если это допустимо).

Авторизация: политики, роли, права и “как не размазать проверки”

Авторизация ломается одинаково в обоих стеках, если проверка прав:

  • разбросана по 30 контроллерам,
  • частично живёт в шаблонах,
  • и не имеет единого “языка” (кто может что делать).

Нормальная цель: вы хотите, чтобы разработчик мог ответить на вопрос:

“Где у нас решается, можно ли пользователю редактировать пост?”

И ответ был: “Вот policy / вот сервис / вот одна точка”.

Laravel: Gates и Policies — читабельный стандарт на проверку прав

Policy как “правила доступа к сущности”

Политика в Laravel — это по сути набор методов:

  • view, create, update, delete,
  • и любые кастомные действия, которые важны для домена.

Пример идеи (упрощённо):

        namespace App\Policies;

use App\Models\Post;
use App\Models\User;

final class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->author_id || $user->is_admin;
    }
}

    

Дальше вы можете использовать это:

  • в контроллере через authorize() / Gate::allows(),
  • в Blade через @can('update', $post),
  • и в роутинге через middleware (в зависимости от подхода проекта).
💡 Практическая мысль
Policies делают права частью языка проекта, а не россыпью if.
📁 Опорные доки Authorization (Gates/Policies)

Laravel: авторизация как часть контроллера (без “сюрпризов”)

Контроллер, который обновляет пост, обычно выглядит так:

        public function update(UpdatePostRequest $request, Post $post)
{
    $this->authorize('update', $post);

    $post->update($request->validated());

    return redirect()->route('posts.show', $post);
}

    
⚠️ Ключевой эффект
Если вы забыли добавить проверку, её будет заметно — проект начинает “скрипеть” при ревью.

Bitrix: группы, роли и права доступа (и почему важно договориться о модели)

В Битриксе “права” исторически живут в нескольких плоскостях:

  • группы пользователей (как базовый RBAC‑слой),
  • права на модули/функции (кто может что делать в рамках модуля),
  • права на контент/сущности (например, на разделы/элементы/файлы — зависит от конкретной подсистемы).

Самая частая практика: группы как роли

В реальных проектах часто делают:

  • “Администраторы”,
  • “Менеджеры”,
  • “Контент‑редакторы”,
  • “Клиенты”,

и проверяют принадлежность к группе.

Упрощённый пример:

        global $USER;

if (!$USER->IsAuthorized()) {
    LocalRedirect('/auth/');
}

$groups = $USER->GetUserGroupArray();
$isManager = in_array(7, $groups, true); // 7 — условный ID группы “Менеджеры”

if (!$isManager && !$USER->IsAdmin()) {
    ShowError('Недостаточно прав.');
    return;
}

    

Это работает, но важно помнить слабое место: “группа как роль” быстро разрастается, если нет правил.

То же самое “по D7”: CurrentUser и проверка групп/операций

Если вы используете D7‑контроллеры или просто хотите унифицировать стиль, удобно брать группы из CurrentUser:

        use Bitrix\Main\Engine\CurrentUser;

$currentUser = CurrentUser::get();
$userId = (int)$currentUser->getId();

if ($userId <= 0) {
    LocalRedirect('/auth/');
}

$groups = $currentUser->getUserGroups(); // массив ID групп
$isManager = in_array(7, $groups, true);

if (!$isManager && !$currentUser->isAdmin()) {
    ShowError('Недостаточно прав.');
    return;
}

    

Ещё один полезный D7‑инструмент — проверка “операций”:

        use Bitrix\Main\Engine\CurrentUser;

if (!CurrentUser::get()->canDoOperation('my_module_edit_post')) {
    ShowError('Недостаточно прав.');
    return;
}

    
💡 Практическая мысль
“Операции” хорошо работают, когда вы описали права в модуле и хотите проверять их одним словом, а не размножать in_array(7, ...) по коду.

Практический совет: одна точка проверки прав

Даже если вы используете группы, старайтесь, чтобы проверки прав были:

  • в одном сервисе/классе,
  • или хотя бы в одном наборе функций,

а не в каждом компоненте/странице.

Например, концептуально:

  • Access::canEditPost($userId, $postId)
  • Access::canManageCatalog($userId)

Смысл тот же, что у policies в Laravel: правила становятся читаемыми и переиспользуемыми.

Bitrix: проверка прав “в коде” — что важно не забывать

Кейс А Не путать “вошёл” и “может”

$USER->IsAuthorized() отвечает только на вопрос “есть ли личность”.
Право на действие нужно проверять отдельно (группа/операция/контекст).

Кейс B Не делать проверки в template.php

Шаблон должен рендерить, а не решать “можно/нельзя”.
Если вы скрыли кнопку “удалить” в шаблоне, но не проверили право на удаление в обработчике — это не безопасность, это косметика.

Кейс C Дублирование правил = будущая ошибка

Если “право менеджера” проверяется в 10 местах, в 11‑м вы забудете.
Лечится только архитектурно: один слой доступа и единые функции/сервисы.

Сессии vs токены: короткая шпаргалка

Сессия (cookie)

  • удобно для браузера,
  • проще защищать CSRF,
  • проще “выйти на всех устройствах” (если есть серверное хранение/инвалидация),
  • обычно меньше ошибок у команды.

Токен (API)

  • удобен для внешних клиентов и интеграций,
  • требует дисциплины по хранению (особенно в браузере),
  • требует понятной модели ротации/отзыва,
  • и почти всегда требует отдельной модели прав (scopes/abilities).
💡 Практическая мысль
Если проект “сайт + личный кабинет”, начинайте с сессий. Токены добавляйте только там, где они реально нужны.

Сравнительная таблица: аутентификация и авторизация

Шкала (как и раньше): от -2 до +2.

Критерий Laravel (баллы) Битрикс (баллы) Комментарий
“Быстрый старт” с готовыми экранами логина/регистрации +2 +2 Laravel: Breeze/Jetstream. Битрикс: платформа и готовые компоненты/страницы.
Понятный стандарт “защитить роут/страницу” +2 +1 Laravel: auth middleware. В Битриксе тоже можно, но часто зависит от архитектуры (страницы/компоненты/контроллеры).
Токены для API и управление ими +2 +1 Laravel: Sanctum/Passport — ясная модель. В Битриксе внешние интеграции часто решают через REST/OAuth, но в “своём API” вам нужно договориться о модели.
Соцлогин/OAuth как типовая задача +2 +1 Laravel: Socialite — стандартный путь. В Битриксе тоже возможно, но чаще с большим количеством проектной специфики.
Авторизация на уровне сущностей (читабельные правила) +2 +1 Laravel: policies/gates читаются как “язык доступа”. В Битриксе это чаще группы/права и собственные проверки, которые важно дисциплинировать.
Интеграция прав с “платформой” (контент/модули/админка) -1 +1 В Laravel вы строите это сами. В Битриксе права — часть платформы и её подсистем.
Итого за статью +9 +7
Общий счёт (накопительный) +66 +37 Счёт накапливается по мере выхода статей.
Заключение
Laravel делает правила доступа “языком проекта”, Bitrix — “частью платформы”

Laravel хорош тем, что задаёт очень ясную инженерную культуру:

  • сессии как базовый путь,
  • token‑подходы для API через Sanctum/Passport,
  • и главное — policies/gates, которые превращают права в читаемые правила.

Битрикс хорош тем, что пользователи и права — это ядро платформы. Это сильно помогает, когда проект живёт внутри “битриксовых” сущностей и модулей. Цена — вам почти всегда нужно договориться о том, как именно вы описываете роли и где живут проверки в коде, иначе права расползаются по страницам и шаблонам.

В следующей части перейдём к теме, где токены, права и интеграции встречаются чаще всего: API‑разработка.

🛠 Практическая работа

Один “личный кабинет” и одно правило доступа — в двух стеках

Цель: сделать минимальный, но честный контур:

  • страница /dashboard, доступна только после входа,
  • страница /admin, доступна только “админам/менеджерам”,
  • и одно правило на сущность: “редактировать пост может автор или админ”.

Задание для Laravel

  1. Подключите Breeze (или Jetstream, если хотите 2FA).
  2. Защитите /dashboard через middleware auth.
  3. Добавьте флаг is_admin пользователю (или роль через пакет), защитите /admin.
  4. Создайте PostPolicy и правило update.
  5. В PostController@update используйте $this->authorize('update', $post).
  6. Спрячьте кнопку “Редактировать” в Blade через @can('update', $post).

Задание для Битрикса

Вариант “сайтовый” (страницы/компоненты):

  1. Сделайте страницу /dashboard/ и в начале проверьте $USER->IsAuthorized().
  2. Сделайте страницу /admin/ и проверьте принадлежность к группе “Менеджеры” (или используйте IsAdmin).
  3. Для сущности “пост” (можно даже без БД — массивом/заглушкой) реализуйте одну функцию доступа: “может редактировать: автор или админ/менеджер”.
  4. В обработчике сохранения (POST) проверьте право до выполнения действия.

Вариант “API‑стайл” (если вы уже делаете контроллеры):

  1. Сделайте контроллерный action updatePostAction.
  2. Перед обновлением проверьте: автор/админ.
  3. Возвращайте предсказуемый JSON для “нет прав” и “успех”.

Подсказка “по‑D7”:

  • аутентификацию можно вынести в prefilters через ActionFilter\Authentication(),
  • метод/CSRF — через ActionFilter\HttpMethod(...) и ActionFilter\Csrf(),
  • роль/группу — проверять внутри action через CurrentUser::get()->getUserGroups() или через canDoOperation(...).

Цель упражнения — почувствовать главный принцип: авторизация должна быть в обработчике, а UI только отражает права (кнопки/ссылки), но не заменяет проверку.

Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.

AI Домовой История

0 / 100

Привет! Я помогу с вопросами по 1С-Битрикс.

Спрашивай про D7, ORM, компоненты или события.

Требуется авторизация

Войдите или зарегистрируйтесь, чтобы задавать вопросы AI-ассистенту.

Войти