Files
medical-mall/pages/mall/admin/MULTI_TERMINAL_REGISTRATION_GUIDE.md

3.4 KiB
Raw Blame History

多端用户注册与身份识别实现指南 (Multi-Terminal Registration Guide)

本档说明了如何在当前的 Supabase 架构下实现“消费者端”、“商家端”及“管理端”的统一注册逻辑并确保用户身份Role在入库时能够自动、准确地被识别。

1. 核心架构原理

系统采用 “前端声明意图 + 后端自动触发” 的模式:

  1. 前端 App:在调用接口注册时,通过 raw_user_meta_data 声明用户的目标角色(如 consumermerchant)。
  2. Supabase Auth:接收并存储这些元数据。
  3. 数据库触发器 (Trigger):在 auth.users 产生新记录的一瞬间,由数据库自动读取元数据,并将用户信息连带其正确的角色属性同步到业务表 ak_users 中。

2. 前端实现步骤 (代码参考)

在各端 App 的注册逻辑中,需在调用 signUp 接口时传递 options.data

消费者端 (Consumer App)

pages/user/register.uvue 中:

const options = new UTSJSONObject()
const metaData = new UTSJSONObject()
metaData.set('user_role', 'consumer') // 核心:声明为消费者
options.set('data', metaData)

const result = await supa.signUp(email, password, options)

商家端 (Merchant App)

在商家端的注册页面中,只需修改 user_role 的值:

metaData.set('user_role', 'merchant') // 核心:声明为商家

3. 数据库实现步骤 (SQL 设置)

为了让数据库能够“看碟下菜”,必须在 Supabase SQL Editor 中运行以下脚本,安装/更新智能触发器:

-- 1. 创建或更新处理函数
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
  -- 向业务表插入数据,并智能识别角色
  INSERT INTO public.ak_users (id, auth_id, email, role, nickname, status)
  VALUES (
    NEW.id, 
    NEW.id, -- 统一使用 Auth ID
    NEW.email,
    -- 核心逻辑:读取 metadata 中的 user_role如果没有传则默认为 'consumer'
    COALESCE(NEW.raw_user_meta_data->>'user_role', 'consumer'),
    -- 默认昵称取邮箱前缀
    split_part(NEW.email, '@', 1),
    1 -- 默认激活状态
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 2. 绑定触发器
DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

4. 三端互不干扰的优势

  • 全自动入库:一旦 SQL 触发器设置完成,前端不再需要手动调用 ensureUserProfileinsert 接口,减少了网络请求和前端报错几率。
  • 物理隔离与 RLS 安全:通过 ak_users 表的 RLS 策略(auth.uid() = id),确保即使用户通过 API 尝试修改他人数据,也会被数据库直接拦截。
  • 统一维护:所有端的注册逻辑在数据库层面是统一的,未来若需增加新角色(如 admin_manager),只需修改触发器逻辑即可,无需大规模重构代码。

5. 开发建议

  • 强制校验:在生产环境下,可以在触发器内增加校验逻辑,防止普通用户通过伪造元数据获得 admin 角色。
  • 日志排查:如果新用户注册后 ak_users 表没有数据,请检查 Supabase 控制台的 Database -> Logs,查看触发器执行是否有报错(通常是唯一索引冲突导致)。

最后更新时间2026-03-10