Безопасность на уровне строк с использованием prisma и postgres
Я использую серверы prisma и yoga graphql с базой данных postgres.
Я хочу реализовать авторизацию для моих запросов в GraphQL. Я видел такие решения, как graphql-shield, которые решают column level security
приятно - это означает, что я могу определить разрешение и в соответствии с ним заблокировать или разрешить определенную таблицу или столбец данных (в терминах graphql, заблокировать целую сущность или определенное поле).
Часть, на которой я застрял, row level security
- фильтрация строк по содержащимся в них данным - скажем, я хочу разрешить вошедшему в систему пользователю просматривать только те данные, которые относятся к нему, поэтому в зависимости от значения в столбце user_id я бы разрешил или заблокировал доступ к этой строке (зарегистрированному у пользователя есть один пример, но есть другие варианты использования в этом жанре).
Этот тип безопасности требует выполнения запроса, чтобы проверить, к каким строкам имеет доступ текущий пользователь, и я не могу найти способ (что не ужасно) реализовать это с помощью призмы.
Если бы я работал без призмы, я бы реализовал это на уровне каждого распознавателя, но поскольку я пересылаю свои запросы в призму, я не контролирую внутренние преобразователи во вложенном запросе.
Но я хочу работать с prisma, поэтому одна из идей, которая у нас возникла, заключалась в обработке этого на уровне БД с использованием политики postgres. Это может работать следующим образом:
- Каждый выполняемый нами запрос будет окружен "начать транзакцию" и "зафиксировать транзакцию"
- Перед запросом я хочу запустить "установить local context.user_id на 5"
- Затем я хочу выполнить запрос (и политика отфильтрует результаты в соответствии с current_setting('context.user_id'))
Чтобы это работало, мне понадобилась бы призма, позволяющая мне либо добавлять запросы pre/post к каждому выполняемому запросу, либо позволять мне устанавливать контекст для базы данных.
Но эти опции недоступны в призме.
Есть идеи?
1 ответ
Ты можешь использовать prisma-client
вместо prisma-binding
,
С prisma-binding
Вы определяете распознаватель верхнего уровня, а затем делегируете в призму для всех вложений.
С другой стороны, prisma-client
возвращает только скалярные значения типа, и вам нужно определить средства разрешения для отношений. Это означает, что вы имеете полный контроль над тем, что вы возвращаете, даже для вложенных запросов. (См. Документацию для примера)
Я бы предложил вам использовать prisma-client
применить ваши фильтры безопасности на полях.
С подходом, который вы хотите использовать, я определенно рекомендую взглянуть на Graphile. Он подходит к безопасности на уровне строк по существу так же, как вы думаете. К сожалению, похоже, что Prisma не поможет вам отойти от написания традиционных методов контроллера в стиле REST в этом отношении.