Я только начинаю знакомиться с 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 в этом контексте? Как я могу адаптировать это, чтобы соответствовать моей схеме?
«Что такое auth в этом контексте?» - это схема, в которой живет функция email(). Вероятно, предоставляется supabase, если вы не знаете об этом.
«Я пытаюсь установить политику обновления для таблицы компаний» — как бы вы хотели, чтобы ваша политика работала?
@Берги, спасибо! Любой, кто связан с компанией, должен иметь возможность обновить эту компанию. В моем примере Боб и Алиса могут обновить информацию о компании 1. Джейн может обновить информацию о компании 2.
ELI5 = Объясните это, как будто мне 5 лет (Другими словами, пожалуйста, не думайте, что у меня много базовых знаний о безопасности на уровне строк ... потому что я этого не знаю ;)
Здесь нужно распаковать несколько вещей.
Auth — это схема, в которой Supabase развертывает связанные с аутентификацией таблицы и вспомогательные функции.
Если вы используете 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. Не было понятно, какая у тебя цель, пока я не прочитала этот комментарий. Я добавил два примера, которые вы можете использовать для достижения этой цели.
Что такое "ЭЛИ5"?