Как я делаю авторизацию в связке Laravel + Vue/React
Когда Laravel работает бэкендом для SPA, самая чувствительная часть – авторизация. Если её запилить «на автомате», начинаются странности: кто-то отваливается после перезагрузки, где-то течёт токен, фронт и бэк по-разному понимают статус сессии.
Расскажу, как я обычно строю авторизацию для Vue/React над Laravel.
1. Сначала выбираю модель: cookie или токен
Я начинаю не с кода, а с ответов на два вопроса:
- фронт и бэк на одном домене / поддомене или на разных
- насколько жёсткие требования к безопасности (особенно по XSS)
Дальше:
-
Один домен → чаще беру Sanctum с cookie-сессией. Браузер сам шлёт cookie, фронту не нужно хранить токен.
-
Разные домены / мобильные клиенты → смотрю в токены (тот же Sanctum, Passport, JWT). Фронт хранит токен и сам кладёт его в заголовок.
Главное: не смешивать всё сразу.
2. Laravel Sanctum с cookie: мой дефолт для SPA
Стандартный сценарий:
1. Настраиваю Sanctum и CORS. 2. Делаю маршрут /login, который:
- валидирует данные,
- вызывает Auth::attempt,
- возвращает 204 или данные пользователя.
- SPA шлёт POST /login с withCredentials: true.
- При запросах к API Laravel использует cookie как обычную сессию.
Плюсы:
- токен живёт в httpOnly cookie
- удобно для чисто веб-клиентов
Минус: сложнее работать с другими платформами (мобильные приложения).
3. Токен-авторизация: когда клиенты разные
Для проектов, где есть мобильные клиенты или отдельные домены, я:
- завожу POST /api/v1/login, который возвращает токен:
{ "token": "…", "user": { ... } }
-
на фронте храню токен:
-
в памяти приложения (желательно),
- либо в secure-хранилищах, а не в localStorage, где это возможно;
- все запросы идут с Authorization: Bearer .
Обязательно добавляю эндпоинт /logout, который инвалидирует токен на сервере.
4. Как фронт понимает, авторизован ли пользователь
Я стараюсь сделать один «источник правды»:
- при загрузке SPA фронт делает запрос /api/v1/me
- если ответ 200 → сохраняю пользователя в сторе
- если 401 → показываю гостевой интерфейс / форму логина
Так не нужно гадать по наличию токена, жива ли сессия.
5. Ошибки и UX вокруг логина
Нюансы, которые сильно влияют на ощущение «оно работает»:
- чётко различаю:
- 422 – неверные данные формы (подсвечиваю поля),
- 401 – неверная пара логин/пароль,
- 429 – слишком много попыток;
-
при истечении сессии API отдаёт 401, фронт:
-
чистит стор пользователя,
- редиректит на логин,
- показывает понятное сообщение.
Важно не оставлять пользователя с немой формой, которая «ничего не делает».
6. Чек-лист настроенной авторизации
- Понятно, один это домен или несколько, выбрана модель (cookie или токен)
- Есть отдельные маршруты /login, /logout, /me
- Laravel возвращает осмысленные коды: 200/204, 401, 422
- Во Vue/React есть единый слой работы с API (axios-инстанс и интерсепторы)
- Состояние пользователя хранится в сторе/контексте и синхронизируется через /me
- При 401 фронт очищает данные и уводит пользователя на логин
Итог
Авторизация в связке Laravel + Vue/React не про «какой пакет взять», а про договорённость: как выглядят маршруты, где живёт токен/сессия, какие коды ошибок возвращает бэк и что фронт делает в ответ. Когда этот контракт чёткий, логин и работа с сессией перестают быть хрупким местом, а становятся просто ещё одной предсказуемой частью приложения.