Logo花火漫画开发文档
函数详情

用户管理(Admin)

admin-create-user、admin-reset-password、manage-user-role 三个管理后台函数的鉴权、操作与审计日志

本页面描述管理中心(Dashboard)使用的三个用户管理 Edge Function。它们共享相同的鉴权模型和审计日志机制,仅供 admin 角色调用。

通用机制

鉴权模型

三个函数使用相同的两阶段鉴权:

JWT 校验(Supabase 网关层):verify_jwt: true,拦截无效或过期的 JWT

角色检查(函数层):通过 supabase.auth.getUser() 获取调用者信息,检查 app_metadata.role === 'admin',非 admin 返回 403

角色信息存储在 auth.users.app_metadata.role 中,取值为 admin / editor / userapp_metadata 只能通过 Admin API 修改,用户自身无法篡改。

审计日志

每次操作成功后,函数会向 admin_logs 表写入一条记录,包含操作者、目标用户、操作类型、客户端 IP 和详情。即使日志写入失败,操作本身不会回滚(已完成),但会输出 CRITICAL 级别日志。

action_type对应函数说明
USER_CREATEadmin-create-user创建新用户
RESET_PASSWORDadmin-reset-password重置密码
USER_PROMOTEmanage-user-role提升为 editor
USER_DEMOTEmanage-user-role降级为 user

双客户端模式

三个函数都创建了两个 Supabase 客户端:

  • Client A(ANON_KEY + 用户 JWT):用于验证调用者身份
  • Client B(SERVICE_ROLE_KEY):用于执行需要 Admin API 权限的操作(创建用户、修改密码、更新 app_metadata

admin-create-user

在管理中心创建新用户账号。

属性
方法POST
JWT 校验
CORS支持
调用方Dashboard 管理中心

请求参数

Prop

Type

此函数只能创建 usereditor 角色。不能通过此函数创建 admin——admin 账号需直接操作数据库。

处理流程

参数校验:邮箱格式、密码长度 ≥ 6、角色为 user / editor、理由 ≥ 5 字符

调用 Admin APIsupabaseAdmin.auth.admin.createUser() 创建用户,设置 email_confirm: true(跳过邮箱验证),将 role 写入 app_metadatadisplay_name 写入 user_metadata

邮箱冲突处理:如果邮箱已注册,返回 409 Conflict

写入审计日志:记录操作者、新用户 ID、角色、创建理由

响应示例

{
  "message": "User created successfully",
  "user": {
    "id": "uuid",
    "email": "newuser@example.com",
    "role": "editor",
    "display_name": "新编辑"
  }
}

审计日志 details

{
  "email": "newuser@example.com",
  "role": "editor",
  "display_name": "新编辑",
  "reason": "新招的漫画编辑,负责日漫区",
  "created_by_admin": true
}

admin-reset-password

管理员为目标用户重置密码。

属性
方法POST
JWT 校验
CORS支持
调用方Dashboard 管理中心

请求参数

Prop

Type

处理流程

鉴权:验证调用者为 admin

修改密码supabaseAdmin.auth.admin.updateUserById(target_user_id, { password })

写入审计日志:记录操作者和目标用户(不记录密码明文)

响应示例

{ "message": "Password updated successfully" }

此函数不检查目标用户的角色——admin 可以重置任何人的密码,包括其他 admin。使用时需谨慎。


manage-user-role

提升或降级用户角色(user ↔ editor)。

属性
方法POST
JWT 校验
CORS支持
调用方Dashboard 管理中心

请求参数

Prop

Type

处理流程

鉴权:验证调用者为 admin

获取目标用户:通过 admin.getUserById() 查询目标用户信息

保护检查:如果目标用户是 admin,返回 403——不允许通过此函数修改其他 admin 的角色

更新角色admin.updateUserById()app_metadata.role 设为 editor(promote)或 user(demote)

写入审计日志:记录变更前后的角色、操作类型和理由

角色变更规则

promote: user → editor   (获得内容编辑权限)
demote:  editor → user   (移除编辑权限)

不能将用户提升为 admin,也不能降级 admin。admin 角色的管理需直接操作数据库。

响应示例

{
  "message": "User promoted successfully",
  "new_role": "editor",
  "user_id": "target-uuid"
}

审计日志 details

{
  "previous_role": "user",
  "new_role": "editor",
  "action_requested": "promote",
  "note": "提升为编辑 - 理由: 负责韩漫区内容上传"
}

角色体系

三种角色的权限层级:

角色来源能力
user默认注册普通用户,阅读漫画、发表评论
editoradmin 指定编辑权限,管理漫画内容(上传、编辑、排序)
admin直接操作数据库全部权限,包括用户管理、系统配置

角色存储在 auth.users.app_metadata.role,被 RLS 策略中的 is_admin()is_admin_or_editor() RPC 函数引用。

相关数据表

admin_logs

Prop

Type

Secrets 依赖

Secret说明
SUPABASE_URL系统自带
SUPABASE_ANON_KEY系统自带,用于验证调用者身份
SUPABASE_SERVICE_ROLE_KEY执行 Admin API 操作(创建用户、修改密码、更新 metadata)

安全注意事项

  • 所有操作均需 admin 角色,非 admin 调用一律返回 403
  • admin-reset-password 没有角色保护:admin 可以重置任何人的密码(包括其他 admin),如需限制应在函数层添加检查
  • manage-user-role 有 admin 保护:不允许通过此函数修改 admin 角色,防止 admin 之间互相降权
  • 理由必填:admin-create-user 和 manage-user-role 要求提供操作理由(≥ 5 字符),确保审计可追溯
  • IP 记录:从 x-forwarded-for 头提取客户端 IP,可能经过代理,不完全可靠但可作为参考

On this page