用户认证和信息模块
约 976 字大约 3 分钟
2025-08-14
概述
用户信息系统基于 Supabase Auth 的 auth.users 表,通过用户元数据(raw_user_meta_data)存储扩展信息。系统不再使用独立的 user_info 表,而是直接从 auth.users 和 user_metadata 获取所有用户信息。
数据存储结构
auth.users 表
使用 Supabase Auth 内置的 auth.users 表存储基础用户信息:
-- Supabase Auth 内置表结构(简化版)
auth.users (
id UUID PRIMARY KEY,
email VARCHAR(255),
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
raw_user_meta_data JSONB,
-- 其他 Supabase Auth 字段...
);用户元数据结构
用户扩展信息存储在 raw_user_meta_data JSONB 字段中:
{
"full_name": "用户真实姓名",
"role": "student|teacher|admin",
"avatar_url": "用户头像URL(可选)",
"phone": "用户手机号(可选)",
"is_active": true
}字段说明
| 字段名 | 存储位置 | 数据类型 | 默认值 | 描述 |
|---|---|---|---|---|
id | auth.users.id | UUID | - | 用户唯一标识 |
email | auth.users.email | VARCHAR(255) | - | 用户邮箱地址 |
full_name | metadata.full_name | STRING | 用户真实姓名 | |
role | metadata.role | STRING | 'student' | 用户角色:admin/student/teacher |
avatar_url | metadata.avatar_url | STRING | null | 用户头像 URL |
phone | metadata.phone | STRING | null | 用户手机号码 |
is_active | metadata.is_active | BOOLEAN | true | 账户激活状态 |
created_at | auth.users.created_at | TIMESTAMPTZ | NOW() | 记录创建时间 |
updated_at | auth.users.updated_at | TIMESTAMPTZ | NOW() | 记录最后更新时间 |
用户角色枚举
| 枚举值 | 中文名称 | 描述 |
|---|---|---|
admin | 系统管理员 | 拥有系统最高权限 |
teacher | 教师用户 | 可以创建和管理课程 |
student | 学生用户 | 可以参与课程学习,默认角色 |
辅助函数
系统提供了一系列辅助函数来从用户元数据获取信息:
1. get_user_role(user_id UUID)
获取用户角色:
CREATE OR REPLACE FUNCTION get_user_role(user_id UUID)
RETURNS text
LANGUAGE sql
STABLE
SECURITY DEFINER
AS $$
SELECT COALESCE(
(raw_user_meta_data->>'role')::text,
'student'
)
FROM auth.users
WHERE id = user_id;
$$;2. is_user_active(user_id UUID)
检查用户是否激活:
CREATE OR REPLACE FUNCTION is_user_active(user_id UUID)
RETURNS boolean
LANGUAGE sql
STABLE
SECURITY DEFINER
AS $$
SELECT COALESCE(
(raw_user_meta_data->>'is_active')::boolean,
true
)
FROM auth.users
WHERE id = user_id;
$$;3. get_user_full_name(user_id UUID)
获取用户全名:
CREATE OR REPLACE FUNCTION get_user_full_name(user_id UUID)
RETURNS text
LANGUAGE sql
STABLE
SECURITY DEFINER
AS $$
SELECT COALESCE(
raw_user_meta_data->>'full_name',
email
)
FROM auth.users
WHERE id = user_id;
$$;用户注册流程
1. 前端注册
使用 Supabase Auth API 进行用户注册:
const { data, error } = await supabase.auth.signUp({
email: credentials.email,
password: credentials.password,
options: {
data: {
full_name: credentials.full_name,
role: credentials.role || "student",
}
}
});2. 元数据构建
注册成功后,用户信息从元数据构建:
const userInfoData = {
id: data.user.id,
email: data.user.email || '',
full_name: metadata?.full_name || data.user.email || '',
role: metadata?.role || 'student',
avatar_url: metadata?.avatar_url || null,
phone: metadata?.phone || null,
is_active: true,
created_at: data.user.created_at || '',
updated_at: data.user.updated_at || data.user.created_at || '',
};用户登录流程
1. 前端登录
使用 Supabase Auth API 进行用户登录:
const { data, error } = await supabase.auth.signInWithPassword({
email: credentials.email,
password: credentials.password,
});2. 用户信息获取
登录成功后,从用户元数据构建用户信息,无需额外的数据库查询。
RLS 策略
所有依赖用户信息的表的 RLS 策略已更新为使用辅助函数:
示例策略
-- 学生课程选修策略
CREATE POLICY "学生查看自己的选课" ON public.student_course_enrollments
FOR SELECT USING (
student_id = auth.uid() OR
get_user_role(auth.uid()) = 'admin'
);
-- 教师课程管理策略
CREATE POLICY "管理员教师管理课程" ON public.courses
FOR ALL USING (get_user_role(auth.uid()) IN ('admin', 'teacher'));数据类型定义
枚举类型
-- 用户角色枚举类型(用于函数参数验证)
CREATE TYPE user_role AS ENUM ('admin', 'student', 'teacher');迁移历史
2025-08-14: 用户信息模块重构
- 移除:
public.user_info表及其相关触发器、索引、RLS策略 - 更新: 所有 RLS 策略使用辅助函数从
auth.users获取用户信息 - 添加: 用户信息辅助函数 (
get_user_role,is_user_active,get_user_full_name) - 优化: 简化认证流程,减少数据库查询
优势
性能优势
- 减少了数据库表连接操作
- 用户信息直接从认证会话获取
- 无需额外的数据库查询
维护优势
- 消除了数据同步问题
- 简化了用户管理流程
- 减少了数据库维护复杂度
安全优势
- 用户信息与认证状态原生关联
- 避免了数据不一致的风险
- 简化了权限管理逻辑
版权所有
版权归属:Evoliant
许可证:MIT