Laravel Snippets - API Auth
28.02.2021
Я решил продолжить тему с функционалом авторизации на Laravel, начатую в Laravel Snippets - Livewire Auth, и реализовал ещё один каркас для авторизации, но уже через API.
Готовая реализация - https://github.com/poymanov/ls-api-auth
К созданию ещё одного "сниппета" меня подтолкнуло видео от канала Laravel Daily.
В данном видео были реализованы только регистрация и авторизация. Я пошел немного дальше и сделал:
- Сброс пароля;
- Отправку письма для активации учетной записи после регистрации;
- Активация учетной записи - обязательное требование при авторизации;
- Повторая отправка письма с ссылкой активации учетной записи;
- Завершение пользовательского сеанса (logout).
Вся авторизация происходит, как и положено, через Bearer Token и благодаря Laravel Sanctum настраивается очень просто:
Для модели пользователя задаем необходимость использования токенов с помощью подключения трейта HasApiTokens
:
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable, HasApiTokens;
При авторизации пользователя, после прохождения всех валидаций, создаем авторизационный токен и возвращаем его в ответе:
$user->createToken('auth-token')->plainTextToken
Когда необходимо завершить пользовательский сеанс, просто очищаем все ранее созданные токены конкретного пользователя:
$user->tokens()->delete();
Как видно выше, все гораздно проще, чем делать нечто подобное через Laravel Passport.
Теперь разберём основные endpoint приложения:
Регистрация пользователя
POST /registartion
Отправляем основные данные нового пользователя - имя, email, пароль (с подтверждением). На выходе получаем ответ с успешным статусом и письмо на почту с просьбой подтвердить учетную запись:
Повторное письмо с активацией учетной записи
POST /resend-email-verification
Если пользователь по каким-то причинам не смог получить письмо об активации или потерял его, он может повторно получить такое письмо. Отправляем email зарегистрированного пользователя, на выходе снова получаем письмо на почту с ссылкой для активации учетной записи (такое же, как и после регистрации).
Авторизация
POST /login
Авторизация зарегистрированного ранее пользователя, при условии что он подтвердил свою учетную запись. Отправляем логин/пароль, в отчет получаем авторизационный токен вида:
4|bVe755KAkAibRfAR5xrIEkJDcXtQe6XCD6D7TUmQ
Подтверждение учетной записи
POST /verify-email/{id}/{hash}
Подтверждение учетной записи зарегистрированного ранее пользователя. URL содержит id пользователя, хэш от адреса его учетной записи и ключ подписанной ссылки от функционала Laravel Signed Url. В ответ получаем успешный статус и даем возможность пользователю авторизовываться.
Запрос на сброс пароля
POST /forgot-password
Пользователь может сбросить свой пароль, если забыл его. В запросе необходимо отправить email пользователя, для которого необходимо сбросить пароль, в ответ получаем письмо с ссылкой на сброс пароля:
POST /reset-password
Непосредственный сброс пароля пользователя и запись нового пароля вместе старого. Запрос должен содержать специальный токен, email пользователя и новый пароль (с подтверждением). После процесса сброса пользователь может авторизовываться, используя новый пароль.
Завершение сеанса пользователя (logout)
POST /logout
Запрос должен быть отправлен с токеном авторизации (Bearer Token). В результате запроса завершается сеанс пользователя (все авторизационные токены удаляются).
Профиль пользователя
GET /profile
Запрос должен быть отправлен с токеном авторизации (Bearer Token). В результате запроса возвращаются данные текущего авторизованного пользователя в виде json:
{
"id": 5,
"name": "test",
"email": "test@test.ru"
}
Помимо данного описания по корневому адресу приложения доступна документация в формате Swagger:
Интересные моменты, которые узнал в процессе разработки
- В процессе некоторых запросов отправляются письма с ссылками. По-хорошему они должны ссылаться на frontend, с которого будет уходить специальный запрос на backend. Как это сделать? Ответ на этот вопрос волновал не только меня. Реализация - в письме на API отправляем ссылку на frontend с зашифрованным url, который может быть расширован на клиенте и по которому будет сделан запрос к API. Пример - формирование ссылки для подтверждения учетной записи.
- В тестах, для правильного понимания того, что письмо ушло нужно проверить, что конкретное уведомление (не письмо!) было использовано минимум один раз:
Notification::assertTimesSent(1, VerifyEmail::class);
Об авторе
Пойманов Николай
PHP-разработчик