Files
medical-mall/pages/user/test/README.md
2026-01-26 21:34:17 +08:00

5.8 KiB
Raw Blame History

用户认证相关 SQL 文件说明

本目录包含用户登录/注册相关的数据库表结构和触发器。

📁 文件说明

1. USER_AUTH_SCHEMA.sql 第一步

创建用户认证相关的表结构:

  • ak_users - 业务用户资料表(与 auth.users 关联)
  • users - 轻量用户表(用于统计)
  • user_sessions - 用户会话表(用于在线统计)
  • RLS 策略 - 行级安全策略
  • 触发器 - 自动更新 updated_at 字段
  • RPC 函数 - upsert_user_profile(用于创建/更新用户资料,绕过 RLS

执行顺序:首次部署时执行

执行方式:在 Supabase Dashboard 的 SQL Editor 中执行


2. USER_AUTH_TRIGGER.sql 第二步(推荐)

创建数据库触发器,在 auth.users 表插入新用户时自动创建 ak_users 记录。

优点

  • 完全自动化,无需前端处理
  • 即使邮箱验证开启也能正常工作
  • 不依赖前端 token

执行顺序:在 USER_AUTH_SCHEMA.sql 之后执行

执行方式:在 Supabase Dashboard 的 SQL Editor 中执行(需要 superuser 权限Dashboard 默认有)

注意:如果无法创建触发器(权限问题),可以跳过此文件,使用 RPC 函数方案。


3. USER_AUTH_TEST_DATA.sql(可选)

插入测试用户数据,用于开发和测试。

执行顺序:在表结构创建后执行


🚀 快速部署

方式一:使用触发器(推荐)

  1. 执行表结构

    -- 在 Supabase Dashboard 执行
    -- 复制 pages/user/test/USER_AUTH_SCHEMA.sql 的内容并执行
    
  2. 创建触发器

    -- 在 Supabase Dashboard 执行
    -- 复制 pages/user/test/USER_AUTH_TRIGGER.sql 的内容并执行
    
  3. 验证

    -- 检查函数是否存在
    SELECT * FROM pg_proc WHERE proname = 'upsert_user_profile';
    
    -- 检查触发器是否存在(如果执行了 USER_AUTH_TRIGGER.sql
    SELECT * FROM pg_trigger WHERE tgname = 'on_auth_user_created';
    

方式二:仅使用 RPC 函数(如果触发器无法创建)

  1. 执行表结构

    -- 在 Supabase Dashboard 执行
    -- 复制 pages/user/test/USER_AUTH_SCHEMA.sql 的内容并执行
    
  2. 验证 RPC 函数

    -- 检查函数是否存在
    SELECT * FROM pg_proc WHERE proname = 'upsert_user_profile';
    

🔧 工作原理

方案一:数据库触发器(推荐)

  1. 用户注册 → Supabase Auth 在 auth.users 表中创建记录
  2. 数据库触发器自动执行 → 在 ak_users 表中创建对应记录
  3. 前端无需处理 → 用户资料自动创建

方案二RPC 函数

  1. 用户注册 → 前端获取 user 对象
  2. 前端调用 ensureUserProfile() → 内部调用 upsert_user_profile RPC 函数
  3. RPC 函数使用 SECURITY DEFINER → 绕过 RLS 策略,创建用户资料

⚠️ 重要说明

RLS 策略

ak_users 表已启用 RLS策略如下

  • SELECT:用户只能查看自己的资料(auth.uid() = id
  • INSERT:用户只能插入自己的资料(auth.uid() = id
  • UPDATE:用户只能更新自己的资料(auth.uid() = id

注册时的问题

注册时如果邮箱验证未开启Supabase 会返回 session此时有 token可以直接插入。

如果邮箱验证已开启,注册后没有 session此时没有 tokenauth.uid() 返回 nullRLS 策略会阻止插入。

解决方案

  1. 使用数据库触发器(自动创建,无需 token
  2. 使用 SECURITY DEFINER RPC 函数(绕过 RLS
  3. ⚠️ 用户登录后自动创建(在 getCurrentUser 中处理)

🔍 验证和测试

测试注册流程

  1. 注册新用户

    • 在前端注册页面输入邮箱和密码
    • 点击注册
  2. 检查数据库

    -- 检查 auth.users 表中是否有新用户
    SELECT id, email, created_at FROM auth.users ORDER BY created_at DESC LIMIT 5;
    
    -- 检查 ak_users 表中是否有对应记录
    SELECT id, email, username, created_at FROM ak_users ORDER BY created_at DESC LIMIT 5;
    
  3. 如果 ak_users 中没有记录

    • 检查是否执行了 USER_AUTH_TRIGGER.sql
    • 检查触发器是否创建成功
    • 检查 RPC 函数是否创建成功
    • 查看浏览器控制台的错误信息

📚 相关文件

  • pages/user/register.uvue - 注册页面
  • pages/user/login.uvue - 登录页面
  • utils/sapi.uts - ensureUserProfile 函数
  • utils/store.uts - getCurrentUser 函数(登录后自动创建资料)

🐛 故障排查

问题:注册后 ak_users 表中没有记录

可能原因

  1. 未执行 USER_AUTH_SCHEMA.sqlRPC 函数不存在)
  2. 未执行 USER_AUTH_TRIGGER.sql(触发器不存在)
  3. RLS 策略阻止插入(没有 token
  4. 邮箱验证已开启,注册后没有 session

解决方案

  1. 执行 USER_AUTH_SCHEMA.sql 创建 RPC 函数
  2. 执行 USER_AUTH_TRIGGER.sql 创建触发器(推荐)
  3. 或者等待用户登录后自动创建(在 getCurrentUser 中处理)

问题RPC 函数调用失败

检查

-- 检查函数是否存在
SELECT proname, prosrc FROM pg_proc WHERE proname = 'upsert_user_profile';

-- 检查权限
SELECT grantee, privilege_type 
FROM information_schema.routine_privileges 
WHERE routine_name = 'upsert_user_profile';

解决:重新执行 USER_AUTH_SCHEMA.sql 中的函数创建部分。


下一步

执行完 SQL 文件后:

  1. 测试注册功能

    • 在前端注册新用户
    • 检查 ak_users 表中是否有新记录
  2. 测试登录功能

    • 使用注册的账号登录
    • 检查是否能正常获取用户资料
  3. 检查前端页面

    • 个人中心页面是否能正常显示用户信息