Как настроить политику обновления PostgreSQL RLS для отношения «один ко многим»?

Я только начинаю знакомиться с PostgreSQL RLS и совсем запутался. У меня есть следующие таблицы:

users
| id|role          |email            |
|--:|:-------------|:----------------|
|  1|authenticated | bob@gmail.com   |
|  2|authenticated | alice@gmail.com |
|  3|authenticated | jane@gmail.com  |
|  4|authenticated | mark@gmail.com  |

profiles
| id|name  | company_id|
|--:|:-----|----------:|
|  1|Bob   |          1|
|  2|Alice |          1|
|  3|Jane  |          2|
|  4|Mark  |         NA|

companies
| id|name |
|--:|:----|
|  1|ABC  |
|  2|DEF  |

Обратите внимание, что я использую Supabase, которая автоматически настраивает таблицу пользователей и роли.

Я пытаюсь установить политику обновления для таблицы компаний. В Supabase есть стартовый шаблон, который выглядит так

CREATE POLICY "companies"
ON public.companies
FOR UPDATE USING (
  auth.email() = email
) WITH CHECK (
  auth.email() = email
);

Может кто-нибудь ЭЛИ5? Что такое auth в этом контексте? Как я могу адаптировать это, чтобы соответствовать моей схеме?

Что такое "ЭЛИ5"?

Bergi 10.01.2023 17:57

«Что такое auth в этом контексте?» - это схема, в которой живет функция email(). Вероятно, предоставляется supabase, если вы не знаете об этом.

Bergi 10.01.2023 17:58

«Я пытаюсь установить политику обновления для таблицы компаний» — как бы вы хотели, чтобы ваша политика работала?

Bergi 10.01.2023 17:59

@Берги, спасибо! Любой, кто связан с компанией, должен иметь возможность обновить эту компанию. В моем примере Боб и Алиса могут обновить информацию о компании 1. Джейн может обновить информацию о компании 2.

Ben 10.01.2023 19:39

ELI5 = Объясните это, как будто мне 5 лет (Другими словами, пожалуйста, не думайте, что у меня много базовых знаний о безопасности на уровне строк ... потому что я этого не знаю ;)

Ben 10.01.2023 20:28
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
1
5
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь нужно распаковать несколько вещей.

Что такое auth в этом контексте?

Auth — это схема, в которой Supabase развертывает связанные с аутентификацией таблицы и вспомогательные функции.

Что делает функция auth.email()?

Если вы используете PSQL, вы можете проверить определение этих вспомогательных функций:

\df+ auth.email


select     
coalesce(     
nullif (current_setting('request.jwt.claim.email', true), ''),
(nullif (current_setting('request.jwt.claims', true), '')::jsonb ->> 'email')
)::text 

Итак, это функция для проверки того, что адрес электронной почты пользователя совпадает с адресом аутентифицированного пользователя. Это делается для того, чтобы пользователь пытался обновить свою собственную строку. Обратите внимание, что эта функция устарела. Текущая рекомендация — использовать вместо этого auth.jwt() ->> 'email'.

Это вспомогательные функции, перечисленные в схеме аутентификации:

  • auth.email()
  • auth.jwt()
  • auth.role()
  • auth.uid()

Изучаем дальше:

Документация также намекает на более сложный сценарий, когда только пользователи с определенным окончанием электронной почты могут что-то обновлять:

create policy "Only Blizzard staff can update leaderboard"
  on my_scores
  for update using (
    right(auth.jwt() ->> 'email', 13) = '@blizzard.com'
  );

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

Использование настраиваемых утверждений для создания политики обновления компании:

Установите настраиваемые утверждения, запустив SQL-скрипт в Редакторе SQL:

Установите претензию для пользователя:

select set_claim('00000-0000-45c1-8dfb-6eeb7cf0b92e', 'company', '1');

Затем вы можете использовать его в политиках RLS:

CREATE POLICY "User can update team details if they belong to the company."
ON public.companies
FOR UPDATE USING (
  get_my_claim('company') = id
);

Другой способ добиться этого — использовать соединения в RLS, но это будет менее эффективно, поскольку вы используете запрос соединения для проверки каждого обновления.

+1 это очень хорошо написано и полезно. Но мне все еще не ясно, как написать конкретную политику, которую я преследую.

Ben 10.01.2023 19:39

Спасибо за отзыв, @Ben. Не было понятно, какая у тебя цель, пока я не прочитала этот комментарий. Я добавил два примера, которые вы можете использовать для достижения этой цели.

Mansueli 10.01.2023 20:48

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