Pull to refresh

Comments 5

я так и не понял есть какие автоматизации с хранением на фронте чтобы при запросе на api, api не лазило на каждый запрос в базу для проверки «есть ли доступ к документу» для допустим: пользователь покупает подписки на 10 статей(авторов) на месяц

это от вас зависит. Сделать это можно как и раньше. Вы можете с сущностью вычислить доступ пользователя.
Что-то в таком духе (могут быть ошибки в синтаксисе):
SELECT new R(entity, (SELECT exists(*) FROM ppa where ppa.person = ?2 AND ppa.page = ?1 AND ppa.valid_until > CURRENT_TIMESTAMP ) FROM p WHERE p.id = ?1


Вам не нужно ничего перерасчитывать на фронте. Либо можно вовсе отдельную ручку сделать, отдаете туда идентификаторы статей/авторов, в ответ получаете карту ид=булев.


То же самое, если вам нужно массово получать статьи, но только те, на которые у вас есть подписки, к вашим условиям фильтрации добавляете дополнительное — существование записи ppa с нужными полями. Постгрес это делает очень быстро, особенно в случае индекс онли скана, что и должно быть.

использование JWT токенов может быть такой автоматизацией на фронте.

в полученном от сервиса авторизации JWT токене клиент передаёт доступный список ему ролей и разрешений в нужный ему сервис.

А поскольку JWT токен подписан шифровальной подписью, то сервисы ему доверяют (но проверяют).

Если я правильно понял, вы предлагаете хранить связь пользователь-роль-объект доступа в каждом ресурсном микросервисе, но всё равно, при наличии глобальных ролей, обращаться в сервис ролей за ними, тем самым делая на один запрос к какому-либо ресурсу 1 сетевой запрос и 1 запрос в БД.

Не проще/правильнее ли хранить весь список ACL(в перемешку с глобальными ролями, у которых нет объектов доступа) в сервисе аутентификации/авторизации, и при получении входящего запроса ресурсным микросервисом, получать весь(или отфильтрованный относительно микросервиса) список ACL и дальше на месте уже решать — давать доступ или нет.
Это решение позволяет не «размазывать» роли пользователя по микросервисам, а держать их централизованно в одном stateless сервисе(можно масштабировать как угодно, под возросшие нагрузки и в ресурсных микросервисах не нужно знать, какой микросервис отвечает за определенную роль/разрешение, соответственно не плодить кучу клиентов к этим сервисам, а иметь всего один клиент к сервису аутентификации/авторизации).
Если я правильно понял, вы предлагаете хранить связь пользователь-роль-объект доступа в каждом ресурсном микросервисе, но всё равно, при наличии глобальных ролей, обращаться в сервис ролей за ними, тем самым делая на один запрос к какому-либо ресурсу 1 сетевой запрос и 1 запрос в БД.

Вам не всегда нужно делать дополнительный запрос в свою БД, при просмотре вы можете за один запрос и сущность получить и флаг видно/нет вытащить, а то и вовсе кинуть человеку 404, если он не должен видеть. Если же это изменение и нужно проверку сделать до, то что мешает держать кеш (Пользователь, Ресурс)=Булев? Он много памяти не скушает. Да и не особо он нужен в таком виде, необходимый запрос к БД выполняется за 0.002 ms, даже если у вас 10 000 000 строк в таблице. А зачем вам каждый раз для одного и того же пользователя получать его роли? В статье про то, что их нужно кешировать как раз и писалось.


Если хранить все доступы в одном месте, то возникает 2 проблемы:


  1. Если идете по пути универсализации, то получается из БД вы вытаскиваете расчеты в приложение (нам же не просто доступ нужен, он может быть условный, временный или еще какой-то) — а это значит, что работать ваш ACL будет как старый пыльный пень, не надо так;
  2. Если же пойдете по пути добавления функционала на каждый микросервис и подгонки БД под это дело, то у вас будет 100500 АПИ на каждый случай жизни и большущая команда разработки авторизации, когда хватило бы полтора инвалида для тех поддержки полностью завершенного и закрытого микросервиса ролевой модели, в который доработки если и потребуются, то на уровне "добавьте роль в БД на проме".

Роли пользователя не размазываются по микросервисам, потому что вы передаете только доступы. Попробуйте смотреть на предложенное с точки зрения иерархии микросервисов и разделения их на сегменты, что-то в духе — эта часть работы с проектами, эта с подбором персонала, а тут у нас обучение. Выкидываете один сегмент — все остальные работают как и работали, выпиливать или удалять из других БД вам ничего не нужно, потому что все лишнее уже само ушло. У вас система получается более гибкой и устойчивой к проблемам. Если у вас один огромный монолит под названием авторизация, то вы туда можете сколько угодно заливать ресурсов, но после определенного порога, вы уже кроме снижения производительности ничего не получите.


Если для вас мега-клиент, который должны использовать все против 1-2 клиента из N является более приемлимым вариантом, то я не знаю что вам тут сказать. Монолитом пахнет может? Это помимо того, что ваш мега-клиент будет стучаться в такой же мега-микросервис, в котором объединено много чего и вам нужна команда человек 40, просто что бы оно жило.

Sign up to leave a comment.

Articles