В прошлой части мы разбирали формы и валидацию — то есть как данные попадают в приложение и как вы держите вход аккуратным.
Теперь следующий “взрослый” слой: кто вообще делает запрос и имеет ли он право сделать то, что просит.
Важное различие терминов (и это место, где чаще всего путаются новички):
- Аутентификация (authentication): “Кто ты?” — установить личность (логин/пароль, сессия, токен, SSO).
- Авторизация (authorization): “Можно ли тебе это?” — проверить права в конкретном контексте (роль, группа, владелец записи, права на раздел и т.д.).
В этой части разберём:
- как Laravel даёт “правильный путь” через Breeze/Jetstream/Fortify + middleware + policies,
- как в Битриксе устроены пользователи (
CUser,UserTable, модульmain) и модель прав (группы/роли/операции), - чем отличается сессия от токена (и почему “сделаю JWT и всё” — не всегда лучший план),
- и как подключается OAuth/соцлогин в обоих подходах.
Аутентификация: сессии, токены и “что считать логином”
Что вы выбираете на самом деле
Когда вы говорите “добавить логин”, вы на самом деле выбираете три вещи:
- Механизм: сессия (cookie) или токен (API).
- Провайдера личности: локальная база пользователей или внешний SSO/OAuth.
- Сценарии безопасности: 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 — про “как логиниться” и “как живёт сессия/учётка”.
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];
}
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 и залогинить.
}
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 и права.
Вариант 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 (в зависимости от подхода проекта).
if.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 хорош тем, что задаёт очень ясную инженерную культуру:
- сессии как базовый путь,
- token‑подходы для API через Sanctum/Passport,
- и главное — policies/gates, которые превращают права в читаемые правила.
Битрикс хорош тем, что пользователи и права — это ядро платформы. Это сильно помогает, когда проект живёт внутри “битриксовых” сущностей и модулей. Цена — вам почти всегда нужно договориться о том, как именно вы описываете роли и где живут проверки в коде, иначе права расползаются по страницам и шаблонам.
В следующей части перейдём к теме, где токены, права и интеграции встречаются чаще всего: API‑разработка.
Один “личный кабинет” и одно правило доступа — в двух стеках
Цель: сделать минимальный, но честный контур:
- страница
/dashboard, доступна только после входа, - страница
/admin, доступна только “админам/менеджерам”, - и одно правило на сущность: “редактировать пост может автор или админ”.
Задание для Laravel
- Подключите Breeze (или Jetstream, если хотите 2FA).
- Защитите
/dashboardчерез middlewareauth. - Добавьте флаг
is_adminпользователю (или роль через пакет), защитите/admin. - Создайте
PostPolicyи правилоupdate. - В
PostController@updateиспользуйте$this->authorize('update', $post). - Спрячьте кнопку “Редактировать” в Blade через
@can('update', $post).
Задание для Битрикса
Вариант “сайтовый” (страницы/компоненты):
- Сделайте страницу
/dashboard/и в начале проверьте$USER->IsAuthorized(). - Сделайте страницу
/admin/и проверьте принадлежность к группе “Менеджеры” (или используйтеIsAdmin). - Для сущности “пост” (можно даже без БД — массивом/заглушкой) реализуйте одну функцию доступа: “может редактировать: автор или админ/менеджер”.
- В обработчике сохранения (POST) проверьте право до выполнения действия.
Вариант “API‑стайл” (если вы уже делаете контроллеры):
- Сделайте контроллерный action
updatePostAction. - Перед обновлением проверьте: автор/админ.
- Возвращайте предсказуемый JSON для “нет прав” и “успех”.
Подсказка “по‑D7”:
- аутентификацию можно вынести в
prefiltersчерезActionFilter\Authentication(), - метод/CSRF — через
ActionFilter\HttpMethod(...)иActionFilter\Csrf(), - роль/группу — проверять внутри action через
CurrentUser::get()->getUserGroups()или черезcanDoOperation(...).
Цель упражнения — почувствовать главный принцип: авторизация должна быть в обработчике, а UI только отражает права (кнопки/ссылки), но не заменяет проверку.