Продолжаем интеграцию. Когда у нас готовы сущности и репозитории создадим сам компонент OAuth-сервера. Для него сгенерируем файлы ключей и сделаем их деплой из Jenkins через Docker Secrets. Сделаем страницу входа и контроллер для генерации и обновления токенов. Все контроллеры покроем функциональными тестами.
По аналогии с Command добавим Query-модель на DBAL для выполнения запросов на чтение данных из модуля. И заодно рассмотрим, как можно избавиться от вызова синглтона SentrySDK в коде наших сервисов и экшенов:
В следующем эпизоде сделаем аутентификацию для страницы просмотра профиля и добавим Cron-команды в Docker Swarm для очистки старых кодов и токенов.
Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Спасибо!
Спасибо!)
Почему Fetcher из FindIdByCreedintials сам строит запрос в базу данных, а не обращается к UserRepository?
Как раз об этом рассказал с 49-ой минуты
Спасибо!
Спасибо!
Спасибо :)
Дмитрий, добавляйте пожалуйста ссылки на гайды - например, с сайта developer.okta.com и oauth2.thephpleague.com
Добрый вечер, Дмитрий.
Подскажите, пожалуйста, если не использовать docker swarm, можно ли как-то прочитать файлы ключей в контейнере?
Пробовал в docker-compose.yml указать файлы ключей через secrets, но на рабочем сервере не получается прочитать файлы, отказано в доступе.
Права на файлы получаются 0400 и создаются от root.
Я пробовал указать mode в docker-compose.yml, но права на файл не менялись.
Локально мы не используем swarm, но секреты нормально подключаются. Так что странно, что не срабатывает.
Да, локально без проблем.
Проблемы на рабочем сервере.
Использование mode не помогло, поискал информацию в инете, но нашёл только то, что эти настройки работают только со swarm-ом, это как бы не полноценная настройка(возможно не так выразился). То есть, как бы я не менял права доступа к файлу через mode, права остаются без изменений.
Вот такими права остаются
Когда я захожу по адресу localhost:8081/authorize то выбивает ошибку:
Key path "file:///run/secrets/jwt_private_key" does not exist or is not readable
Когда я зашел внутрь контейнера api-php-fpm, то внутри папки /run/secrets вижу такое:
-rw------- 1 1000 1000 1675 Oct 22 12:13 jwt_private_key
-rw-rw-r-- 1 1000 1000 451 Oct 22 12:14 jwt_public_key
Соответственно тесты в файле AuthorizeTest не проходят(там ошибка 500).
И что я не так сделал, я без понятия. Там походу ведь docker-compose должен прокидывать туда эти ключи. Он у меня версии 1.25.0. Может дело в нем?
Проблема решена заменой ключей на те, что были в репозитории. Все тесты теперь проходят.
Проблема в том, что у файла jwt_private_key нет прав на чтение. Когда эти файлы были сгенерированы - у них такие права стоят в целях безопасности. Нужно добавить для этого файла права на чтение, только вот не знаю, группы или для всех... Как вариант:
Добрый день, и с наступающим новым годом! В данном уроке, Дмитрий, Вы используете чисты Sql. Получается что название таблиц и столбцов помимо маппинга на сущности ещё и будут в каждом таком запросе. Doctrine решает эту проблему с помощью Dql, плюс даёт возможность расширять этот язык. В своем проекте, я как раз пытаюсь уйти от нативного Sql, в пользу языка запросов к доменной модели.
Здравствуйте. Столкнулся инфраструктурной проблемой и ридмоделями.
В объектах домена понятно дело нет всей информации для построения ридмодели.
К примеру нет понятия кем создана заявка - человеком/ботом. Кто владелец данной заявки, кто редактор.
Но нужна ли она бизнесу? Наверное нет, чем да. Но для построения рид модели понадобилась данная информация.
Как быть?
Единственное что я сейчас вижу это metadata у бизнес объектов куда я могу складировать дополнительную информацию. Создать какой-то отдельный контекст для этого и хранить всё там. Почему отдельный контекст? Потому что это не доменная модель. Бизнесу это не нужно в его контексте. Поэтому и портить доменную модель инфраструктурной частью приложения не хочется. Тогда где же хранить подобную информацию?
Ещё есть кейс - Owner. Когда есть владелец, чего-то и на основании этого надо предоставлять права на редактировании. Опять же это не бизнес требование, а предоставление доступа на уровне приложения. Соотвественно опять не хочется портить бизнес слой контекста. Тогда где хранить?
Хотелось бы услышать Ваши мысли. Благодарю!
Проще всего хранить прямо в заявке.
Добрый вечер.
Вопрос по поводу хранения запросов внутри модуля Auth в папке api/src/Auth/Query
Я так понимаю ответственности (функциональность) классов/интерфейсов находящихся внутри папки api/src/Auth должны быть изолированны в рамках этого модуля Auth и не могут напрямую зависеть от классов и данных других модулей (которые наверняка появятся в проекте в ближайшем будущем).
Отсюда вопрос, если появится sql query который будет содержать к примеру джойны (я понимаю что можно обойтись без джойнов и собирать к примеру в контроллере результат из отельных простых queries, но как показывает практика простой join по производительности чаще всего выигрывает) на таблицы других модулей тогда где их хранить? Ведь папка api/src/Auth/Query уже не подходит в этом случае (как и соответствующая папка в внутри другого модуля), так как query будет зависеть в данном случае от таблиц уже разных модулей.
В каком месте вы бы хранили такие queries?
Заранее спасибо за ваше время!
Про это как раз делал доклад про модульное разделение. А в общем да, собирать данные из разных модулей в контроллере. А если нужен обобщающий запрос, то положить в отдельную папку.
Спасибо за быстрый ответ. Ознакомлюсь с докладом
С позволения Дмитрия добавлю ответ. Суть деления на модули как раз и заключается в том чтобы убрать зависимости между модулями, в том числе и по базе данных. Когда хочется сделать такое - представьте, что это разные базы. Один модуль в Redis, второй в PostgreSQL. Либо вам достался проект, где постепенно переходите с Mysql на PostgreSQL. Если вы организуете связанность по Join таблицы, то вы создали неконтролируемую связь. Завтра кто-то захочет удалить модуль или изменить название таблицы, поменять название столбцов и ваш модуль сломается. Поэтому и предлагается на уровне контроллера делать запрос из разных Query. А с какой базы они работают - нам всё равно. Поэтому лучше использовать разные Query в контроллере или интерфейсы для взаимодействия. Но если всё таки хочется сделать такую Query по каким либо причинам не стоит это делать в папке модуля. Мы иногда такие Query выносим в src/Query. По аналогии stc/Http. Таким образом мы контролируем зависимость.
Доброй ночи! А почему страница для авторизации сделана на стороне "бэка"? Мы же могли ее сделать на фронте и подгружать из реакта?
В OAuth так делают специально для безопасности, чтобы логин и пароль вводили только на сервере аутентификации. Если нужен самый безопасный вариант, то туда стоит перенести также регистрацию и восстановление пароля и защитить все формы от CSRF, чтобы фронтенд и другие клиенты вообще не работали с паролями.
Добрый день, Дмитрий. А можно по подробнее про безопасность? Почему мы не можем генерить форму на реакте?
Представьте, что на каком-либо чужом сайте или в чужом мобильном приложении вы нажали "Войти через Google", а вам вместо редиректа оно прямо у себя выведет форму: "Введите сюда свой email и пароль от Google".
Я испугаюсь, что этот сайт может сохранить мой пароль куда-то у себя перед тем, как полезет логинится с этим адресом и паролем по API.
Именно поэтому у большинства OAuth сервисов не включен Password Grant и в API нет никакого адреса входа по паролю. Возможен только вход через оригинальную форму по редиректу. Чтобы программисты других сайтов или приложений не делали свои формы-посредники.
спасибо
Или войти через: