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:

Интересные моменты, которые узнал в процессе разработки

  1. В процессе некоторых запросов отправляются письма с ссылками. По-хорошему они должны ссылаться на frontend, с которого будет уходить специальный запрос на backend. Как это сделать? Ответ на этот вопрос волновал не только меня. Реализация - в письме на API отправляем ссылку на frontend с зашифрованным url, который может быть расширован на клиенте и по которому будет сделан запрос к API. Пример - формирование ссылки для подтверждения учетной записи.
  2. В тестах, для правильного понимания того, что письмо ушло нужно проверить, что конкретное уведомление (не письмо!) было использовано минимум один раз:
    Notification::assertTimesSent(1, VerifyEmail::class);
    

Об авторе

Пойманов Николай
PHP-разработчик