You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Next.js中用Supabase实现用户账号删除时遇权限错误求助

解决Next.js + Supabase删除用户时的"invalid claim: missing sub claim"错误

错误原因

你使用{ admin: true }创建Supabase服务端客户端时,该客户端以管理员身份运行,不会携带当前用户的会话信息。此时调用client.auth.getUser(),由于缺少用户身份的sub(主体)声明,就会触发这个错误。

修正方案

拆分客户端职责:用普通服务端客户端验证当前用户身份,用admin客户端执行高权限的删除用户操作,同时保留权限验证逻辑。

修正后的deleteUserAction代码

export async function deleteUserAction(id: string) {
  // 普通服务端客户端:用于获取当前登录用户会话
  const userClient = getSupabaseServerClient();
  // Admin客户端:仅用于执行需要高权限的删除用户操作
  const adminClient = getSupabaseServerClient({ admin: true });

  // 获取当前登录用户
  const { data: userData, error: userError } = await userClient.auth.getUser();
  if (userError) throw userError;

  const currentUser = userData.user;
  // 验证用户只能删除自己的账号
  if (currentUser.id !== id) {
    throw new Error('你无权删除此账号');
  }

  // 清理用户关联数据(保留你原有业务逻辑)
  await deletePost(userClient, currentUser.id);
  await deleteSubscription(userClient, currentUser.id);
  await deleteThresholds(userClient, currentUser.id);
  await deleteUser(userClient, currentUser.id);

  // 用Admin客户端执行用户删除
  const { error: deleteError } = await adminClient.auth.admin.deleteUser(currentUser.id);
  if (deleteError) throw deleteError;

  // 登出当前会话
  await userClient.auth.signOut();

  revalidatePath('/');
  redirect('/login');
}

关键调整说明

  • 分离客户端:普通客户端负责会话相关操作(获取当前用户、登出),admin客户端仅处理admin.deleteUser()这类需要服务端全权限的操作
  • 权限校验保留:确保用户只能删除自己的账号,避免越权风险
  • 避免admin客户端调用会话接口:admin模式无用户上下文,不能用来获取当前登录用户

额外注意事项

  • 确认getSupabaseServerClient函数正确区分模式:admin模式需使用Supabase的SERVICE_ROLE_KEY,普通模式会自动携带请求中的用户会话Cookie
  • 关联数据删除操作(如deletePost)无需使用admin权限,用普通客户端即可,减少权限滥用风险

内容的提问来源于stack exchange,提问作者Brayan Cuenca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:26:23