Безопасность на уровне строк с использованием prisma и postgres

Я использую серверы prisma и yoga graphql с базой данных postgres.

Я хочу реализовать авторизацию для моих запросов в GraphQL. Я видел такие решения, как graphql-shield, которые решают column level security приятно - это означает, что я могу определить разрешение и в соответствии с ним заблокировать или разрешить определенную таблицу или столбец данных (в терминах graphql, заблокировать целую сущность или определенное поле).

Часть, на которой я застрял, row level security - фильтрация строк по содержащимся в них данным - скажем, я хочу разрешить вошедшему в систему пользователю просматривать только те данные, которые относятся к нему, поэтому в зависимости от значения в столбце user_id я бы разрешил или заблокировал доступ к этой строке (зарегистрированному у пользователя есть один пример, но есть другие варианты использования в этом жанре).

Этот тип безопасности требует выполнения запроса, чтобы проверить, к каким строкам имеет доступ текущий пользователь, и я не могу найти способ (что не ужасно) реализовать это с помощью призмы.

Если бы я работал без призмы, я бы реализовал это на уровне каждого распознавателя, но поскольку я пересылаю свои запросы в призму, я не контролирую внутренние преобразователи во вложенном запросе.

Но я хочу работать с prisma, поэтому одна из идей, которая у нас возникла, заключалась в обработке этого на уровне БД с использованием политики postgres. Это может работать следующим образом:

  1. Каждый выполняемый нами запрос будет окружен "начать транзакцию" и "зафиксировать транзакцию"
  2. Перед запросом я хочу запустить "установить local context.user_id на 5"
  3. Затем я хочу выполнить запрос (и политика отфильтрует результаты в соответствии с current_setting('context.user_id'))

Чтобы это работало, мне понадобилась бы призма, позволяющая мне либо добавлять запросы pre/post к каждому выполняемому запросу, либо позволять мне устанавливать контекст для базы данных.

Но эти опции недоступны в призме.

Есть идеи?

1 ответ

Решение

Ты можешь использовать prisma-client вместо prisma-binding,

С prisma-bindingВы определяете распознаватель верхнего уровня, а затем делегируете в призму для всех вложений.

С другой стороны, prisma-client возвращает только скалярные значения типа, и вам нужно определить средства разрешения для отношений. Это означает, что вы имеете полный контроль над тем, что вы возвращаете, даже для вложенных запросов. (См. Документацию для примера)

Я бы предложил вам использовать prisma-client применить ваши фильтры безопасности на полях.

С подходом, который вы хотите использовать, я определенно рекомендую взглянуть на Graphile. Он подходит к безопасности на уровне строк по существу так же, как вы думаете. К сожалению, похоже, что Prisma не поможет вам отойти от написания традиционных методов контроллера в стиле REST в этом отношении.

Другие вопросы по тегам