Планирую сделать простой админ CP. Я PHP-разработчик старой школы, где обычно все находится в одном огромном монолитном сервере, и концепция микросервисов не применяется.
В моем следующем приложении я хотел бы иметь:
Экспресс-интерфейс (интерфейс) <----> REST/GraphQL API <-----> сервер БД
Идея состоит в том, чтобы максимально ограничить доступ к БД. Все запросы от пользователей будут направляться только на внешний интерфейс, а API будет использоваться только внутри других серверов в моем решении.
Я настрою IP-фильтры между API и БД и, вероятно, между Frontend и API. Но меня беспокоит - скажем, я хочу, чтобы один админ создавал продукт. Хотя этот пользователь будет аутентифицироваться во внешнем интерфейсе с использованием сеансов, мне нужно, чтобы запросы, идущие к API, также были частично аутентифицированы. Игнорируя IP-фильтры на данный момент, не хочу, чтобы кто-либо мог отправлять запросы REST в API.
У меня есть несколько идей, пожалуйста, выскажите свое мнение:
совместное использование экспресс-сессии между API и интерфейсом с использованием mongodb (вероятно, на еще одном сервере) - я вижу проблемы с задержкой
размещение службы API на том же сервере, что и интерфейс, и использование Redis для обмена сеансами - своего рода поражение цели разделения микросервисов
при входе в систему генерируется jsonwebtoken, который всегда передается между интерфейсом и API для любого действия пользователя - кража файлов cookie будет проблемой, поскольку я могу только проверить, что пользователь вошел в систему, а не то, что он разрешил выполнение определенного действия.
при входе в систему, отправляя закрытый ключ администратору и заставляя его подписывать все запросы, которые перенаправляются к API - это выглядит как перегрузка ЦП
Есть ли какое-либо обычно используемое решение, которое мне не хватает? Является ли разделение внешнего интерфейса и API mitm излишним или хорошей практикой? Я мог бы легко объединить 2 и общаться с БД напрямую из внешнего интерфейса, тогда я могу управлять всем с помощью сеансов, как с PHP.
Спасибо за любой вклад! Ваше здоровье
Более сложной реализацией (1) является использование сеансового сервера. Идея состоит в том, чтобы просто устранить задержку поиска в базе данных, но не узкое место поиска сеанса в целом. Он действует как кэширующий слой. Реализация с нулевым кодированием заключается в использовании чего-то вроде Redis или memcache в качестве хранилища сеансов.
Однако в целом механизм криптографической подписи, такой как JWT, был бы гораздо более масштабируемым, поскольку он не требует поиска операций ввода-вывода. Все, что вам нужно сделать, это убедиться, что токен правильно подписан. И пока вы храните свое приложение в тайне, вы в безопасности. Вы даже можете закодировать такие вещи, как роли пользователей и разрешения, непосредственно в токене, чтобы полностью избежать запроса базы данных для этого.
Ключевая идея JWT заключается в том, что вся безопасность скрыта в бэкенде. Внешний интерфейс только возвращает токен на сервер в качестве доказательства аутентификации.
Но так как внешний интерфейс хранит токен, он может быть захвачен javascript. Одним из решений является использование HttpOnly
файлов cookie в качестве механизма для передачи токенов. Я даже видел реализации, в которых основная часть токена отправляется в заголовке Authorization
, а подпись отправляется в файле cookie HttpOnly. Это предотвращает возможность чтения всего токена сценариями.
Обычная стратегия заключается в том, чтобы хранить токен в localStorage, и любой скрипт, которому удается внедрить себя на вашу страницу, может получить токен с помощью localStorage.getItem()
. Если вы уверены, что инъекция скрипта невозможна, то все должно быть в порядке. Но ты НА САМОМ ДЕЛЕ уверен? А как насчет вредоносных расширений браузера? Отсюда и стратегия использования файлов cookie HttpOnly.
Я использую JWT для своего текущего проекта, и мой интерфейс полностью статичен, поэтому он обслуживается Amazon S3 вместо реального сервера.
спасибо, что вы имеете в виду, что «поскольку интерфейс хранит токен, он может быть захвачен js»? угнали как?