Привет! Меня зовут Таня Козельская и я Full-Stack Developer с семилетним опытом. Сейчас работаю в компании Grid Dynamics. Если вы когда-нибудь, как и я, выбрали или собираетесь выбрать композицию для своего проекта, состоящую из фреймворка Laravel, базы MongoDB и при этом вам нужно выдавать токен для АРI — эта статья может пригодиться.
Немного общей сухой информации. Ну, на всякий случай.
Laravel — это бесплатный веб-фреймворк PHP с открытым кодом, предназначенный для разработки веб-приложений, следующих по архитектурной схеме модели-просмотра (MVC) и основанный на Symfony.
MongoDB — это нереляционная база данных документов, масштабируемая и гибкая, с запросами и индексацией.
Итак, начну рассказ с моего опыта работы. В недалеком 2018 году для одного из своих проектов я выбрала именно такой набор. Поначалу все было отлично, ведь в Laravel есть интегрированный в структуру компонент Passport, который позволяет легко аутентифицировать пользователя, выдавать токен, контролировать время сессии и так далее.
Но оказалось, что есть маленькая проблемка, и по умолчанию Laravel не умеет работать, используя Passport и MongoDB.
Так как в моем проекте были достаточно объемные и разные по структуре данные, отказываться от базы мне не хотелось. Поэтому я начала искать, что можно сделать со всем этим, и, как ни странно, оказалось, что я не одна такая, и уже есть люди, которые столкнулись с этой проблемой и создали специальную библиотеку.
Название библиотеки — designmynight/laravel-mongodb-passport. Если найдете ее на GitHub, то там все очень просто и подробно описано:
composer
; На этом все, дальше можем использовать функцию createToken
. Все работает достаточно стабильно. Но есть один момент — эта полезная библиотека зависит от многих других зависимостей в composer
–файле. И пока Laravel не обновилась до версии 7, все было хорошо. А после обновления использования этой библиотеки стало просто невозможным.
Почему-то разработчики designmynight решили не обновлять свой код для новых версий фреймворка. Так часто бывает с кастомными библиотеками, скажете вы, и я вполне согласна, но на тот момент у меня уже было несколько проектов, которые используют похожую базовую структуру. И с этим нужно было что-то делать.
Сначала я отслеживала репозиторий библиотеки и думала: «Ну, окей, у меня Laravel 6, а получилось только еще одно обновление, можно подождать». Возможно, все будет хорошо и библиотека начнет поддерживать обновление. Между тем на GitHub появляется все больше и больше комментариев о необходимом обновлении, и я одна из тех разработчиц, которые ждут апдейта.
Появляется fork от основной бранчи с комментарием: «Хэй, гайз, все работает для новой версии». Я, конечно, пробую это обновление со странными махинациями при обновлении composer
–файла.
Все это выглядело так, будто я пытаюсь обмануть зависимости и каким-то чудом получить завершение работы команды composer update
.
Должна сказать, что я получила желаемый результат, но касался он только composer
. Несмотря на успешное исполнение, приложение нормально работать не хотело, несоответствие версий зависимостей догнало меня в работе функций логина, того же токена. Пришлось вернуться и подождать еще немного.
Вышла Laravel 8, а обновления библиотеки так и не произошло. Я отставала уже на две версии фреймворка. Я получила время и разрешение от клиента на эксперименты и начала искать выход самостоятельно, исследуя недра фреймворка и Passport.
Мое внимание было направлено на новое расширение Laravel Sanctum, появившееся с 7-й версии. По информации, указанной в документации, с его помощью можно создать легкую систему проверки подлинности для SPA (одностраничных приложений), мобильных приложений и простых API на основе токенов. Это выглядело как нужная мне деталь для приложения. Но и здесь я столкнулась с тем же — использованием MongoDB.
Я решила все-таки попытаться заюзать этот механизм, при этом мне нужно было найти файл, в который шло подключение на стандартный модуль для работы с базой данных и заменить его модуль для работы с MongoDB.
Итак, пошагово это выглядит так:
1. Выполняем базовые команды, указанные в документации Laravel Sanctum для composer:
composer require laravel/sanctum
2. Паблишим провайдер-файл, который позже мы заменим на собственный:
php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider"
3. В модели пользователя подключаем все необходимое для работы Sanctum:
use AppsanctumHasApiTokens; use AppAuthUser as Authenticatable;
Для моей модели это вот эти два файла и при этом модель должна подражать и юзать эти классы:
class User extends Authenticatable implements CanResetPasswordContract { use Notifiable, CanResetPassword, HasApiTokens;
Думаю, что из третьего пункта уже ясно, что нужно создать свою директорию для Sanctum, в которой будет еще много файлов. Также нам необходим файл AuthUser.php
.
4. Файл AuthUser.php
содержит весь базовый код из ядра Laravel Sanctum, но для нас важно то, что мы указываем здесь модуль для работы с базой MongoDB:
use JenssegersMongodbEloquentModel as Model; <?php namespace App; use IlluminateAuthAuthenticatable; use IlluminateAuthMustVerifyEmail; use IlluminateAuthPasswordsCanResetPassword; use IlluminateContractsAuthAccessAuthorizable as AuthorizableContract; use IlluminateContractsAuthAuthenticatable as AuthenticatableContract; use IlluminateContractsAuthCanResetPassword as CanResetPasswordContract; use JenssegersMongodbEloquentModel as Model; use IlluminateFoundationAuthAccessAuthorizable; class AuthUser extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail; }
5. Далее в директорию sanctum нужно поместить следующие файлы:
Эти файлы нужны, поскольку каждый из них вызывает другой, и если не изменить использование на кастомный файл, использующий монгу, то ничего не получится. Начинку этих файлов можно взять из базовой структуры фреймворка и ничего не менять, кроме namespace
. У меня это: Appsanctum;
.
Исключение — файл PersonalAccessToken.php
. В нем нам также следует указать использование MongoDB.
6. Итак, здесь мы подключаем нужный класс для PersonalAccessToken.php
:
<?php namespace Appsanctum; use JenssegersMongodbEloquentModel; use LaravelSanctumContractsHasAbilities; class PersonalAccessToken extends Model implements HasAbilities {
7. Если вы заметили, то в директории Sanctum есть файл SanctumServiceProvider.php
, именно на него нужно изменить в файле configapp.php
базовый провайдер для Sanctum.
На этом настройка и подготовка заканчиваются и можно спокойно использовать способ createToken
для создания и передачи токена пользователю по АРI. У меня это выглядит так:
$user->createToken('app_name', base64_encode($user->_id))->plainTextToken;
Готово!
Надеюсь, мой опыт был интересен и полезен вам. Удачи!
Читайте также: Мастер на все руки: дорожная карта фулстек-разработчика на 2022 год
В благословенные офисные времена, когда не было большой войны и коронавируса, люди гораздо больше общались…
Вот две истории из собственного опыта, с тех пор, когда только начинал делать свою карьеру…
«Ты же программист». За свою жизнь я много раз слышал эту фразу. От всех. Кто…
Отличные новости! Если вы пропустили, GitHub Copilot — это уже не отдельный продукт, а набор…
Несколько месяцев назад мы с командой Promodo (агентство инвестировало в продукт более $100 000) запустили…
Пару дней назад прочитал сообщение о том, что хорошие курсы могут стать альтернативой классическому образованию.…