认证

用户管理

MemFire Cloud采用Supabase认证服务,让管理应用用户变得更简单。

当用户注册时,系统为他们分配了一个唯一的 ID。你可以在你的数据库中的任何地方引用这个ID。例如,你可以创建一个profiles表,使用user_id字段引用用户。

supabase 提供了注册登录退出的接口,并在你的应用程序和网站中管理用户。

行级安全

身份验证只能让你做到这一点。当你需要细化的授权规则时,没有什么比PostgreSQL的行级安全(RLS)更好的了。 supabase 使得打开和关闭RLS变得很简单。

策略

策略是PostgreSQL的规则引擎。它们非常强大和灵活,允许你编写复杂的SQL规则,以适应你独特的业务需求。

有了策略,你的数据库就成了规则引擎。而不是重复地过滤你的查询,像这样...

... 您只需在数据库表上定义一个规则,auth.uid()= user_id,即使从中间件中删除筛选器,您的请求也将返回通过该规则的行:

策略就像where条款

一旦你掌握了这些策略,就很容易理解。你可以把它们看作是在每个查询中添加一个WHERE子句。例如,如果你有一个这样的策略:

create policy "Individuals can view their own todos." on todos for
    select using (auth.uid() = user_id);

每当用户试图从todos表中选择时,它就会转化为这样:

select *
from todos
where auth.uid() = todos.user_id; -- Policy is implicitly added.

工作原理

  1. 用户注册。supabase在“auth.users”表中创建一个新用户。
  2. supabase返回一个新的JWT,其中包含用户的“UUID”。
  3. 对数据库的每个请求都会发送JWT。
  4. MemFireDB检查JWT以确定提出请求的用户。
  5. 可以在策略中使用用户的UID来限制对行的访问。

MemFire Cloud在MemFireDB中提供了一个特殊的函数,auth.uid(),它从JWT中提取用户的uid。这在创建策略时特别有用。

策略实例

下面是一些示例,向您展示PostgreSQL的RLS的强大功能。每个策略都附加到一个表,并且每次访问表时都会执行该策略。

允许读访问

-- 1. Create table
create table profiles (
  id uuid references auth.users,
  avatar_url text
);

-- 2. Enable RLS
alter table profiles
  enable row level security;

-- 3. Create Policy
create policy "Public profiles are viewable by everyone."
  on profiles for select using (
    true
  );
  1. 在公共模式(默认模式)中创建一个名为profiles的表。
  2. 启用行级安全。
  3. 创建一个策略,允许运行所有select查询。

限制更新

-- 1. Create table
create table profiles (
  id uuid references auth.users,
  avatar_url text
);

-- 2. Enable RLS
alter table profiles
  enable row level security;

-- 3. Create Policy
create policy "Users can update their own profiles."
  on profiles for update using (
    auth.uid() = id
  );
  1. 在公共模式(默认模式)中创建一个名为profiles的表。
  2. 启用RLS。
  3. 创建一个策略,允许登录的用户更新他们自己的数据。

带连接的策略

策略甚至可以包括表的连接。这个例子显示了你如何查询 外部表以建立更高级的规则。

create table teams (
  id serial primary key,
  name text
);

-- 2. Create many to many join
create table members (
  team_id bigint references teams,
  user_id uuid references auth.users
);

-- 3. Enable RLS
alter table teams
  enable row level security;

-- 4. Create Policy
create policy "Team members can update team details if they belong to the team."
  on teams
  for update using (
    auth.uid() in (
      select user_id from members
      where team_id = id
    )
  );

具有安全定义函数的策略

策略还可以使用安全定义函数”。这在要限制对链接表的访问的多对多关系中很有用。 在上面的teamsmembers示例之后,此示例演示了如何结合使用安全定义函数和策略来控制对members表的访问。

-- 1. Follow example for 'Policies with joins' above

-- 2.  Enable RLS
alter table members
  enable row level security

-- 3.  Create security definer function
create or replace function get_teams_for_user(user_id uuid)
returns setof bigint as $$
    select team_id
    from members
    where user_id = $1
$$ stable language sql security definer;

-- 4. Create Policy
create policy "Team members can update team members if they belong to the team."
  on members
  for all using (
    team_id in (
      select get_teams_for_user(auth.uid())
    )
  );

验证电子邮件的域名

Postgres有一个函数right(string, n),可以返回一个字符串的最右边的n个字符。 你可以用它来匹配工作人员的电子邮件域名。

-- 1. Create table
create table leaderboard (
  id uuid references auth.users,
  high_score bigint
);

-- 2. Enable RLS
alter table leaderboard
  enable row level security;

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

数据的生存时间

策略也可以用来实现你在Instagram故事或Snapchat中看到的TTL或生存时间功能。 在下面的例子中,stories 表中的行只有在过去24小时内创建时才可用。

-- 1. Create table
create table if not exists stories (
  id uuid not null primary key DEFAULT uuid_generate_v4(),
  created_at timestamp with time zone default timezone('utc' :: text, now()) not null,
  content text not null
);

-- 2. Enable RLS
alter table stories
  enable row level security;

-- 3. Create Policy
create policy "Stories are live for a day"
  on stories
  for select using (
    created_at > (current_timestamp - interval '1 day')
  );

高级策略

使用SQL的全部功能来建立极其高级的规则。

在这个例子中,我们将创建一个postscomments表,然后创建一个依赖于另一个策略的策略。 (在这个例子中,评论策略依赖于帖子策略)。)

create table posts (
  id            serial    primary key,
  creator_id    uuid      not null     references auth.users(id),
  title         text      not null,
  body          text      not null,
  publish_date  date      not null     default now(),
  audience      uuid[]    null -- many to many table omitted for brevity
);

create table comments (
  id            serial    primary key,
  post_id       int       not null     references posts(id)  on delete cascade,
  user_id       uuid      not null     references auth.users(id),
  body          text      not null,
  comment_date  date      not null     default now()
);

create policy "Creator can see their own posts"
on posts
for select
using (
  auth.uid() = posts.creator_id
);

create policy "Logged in users can see the posts if they belong to the post 'audience'."
on posts
for select
using (
  auth.uid() = any (posts.audience)
);

create policy "Users can see all comments for posts they have access to."
on comments
for select
using (
  exists (
    select 1 from posts
    where posts.id = comments.post_id
  )
);

提示

你不需要使用策略

你也可以把你的授权规则放在你的中间件中,类似于你在其他 "后台<->中间件<->前端 "架构中创建安全规则的方式。

策略是一种工具。在 serverless/Jamstack设置的情况下,它们特别有效,因为你根本不需要部署任何中间件。

然而,如果你想为你的应用程序使用另一种授权方法,这也是可以的。MemFire Cloud是单纯的Postgres,所以如果你的应用程序可以使用Postgres,那么它也可以使用MemFire Cloud。

提示:确保为你的所有表启用RLS,这样你的表就无法访问了。然后使用我们提供的Service key,这是为了绕过RLS。

检查MemFire Cloud上的认证设置

在 MemFire Cloud的"我的应用> 认证管理 > 认证设置",你就可以改变一些设置,比如。

  • 网站网址,用于确定在用户确认其电子邮件地址或试图使用魔法链接登录后将其重定向到哪里。
  • 禁用电子邮件确认功能。

avatar

不要在客户端使用服务密钥

MemFire Cloud 提供特殊的Service key密钥,可用于绕过所有 RLS。 这些键不应该在浏览器中使用,也不应该暴露给客户,但它们对管理任务很有用。

results matching ""

    No results matching ""