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

Node后端基于Supabase Auth重置密码时遇Auth session缺失问题

问题描述

在后端处理用户重置密码流程时,需求为:用户收到重置密码邮件后,使用URL中的token完成登录并更新密码。但调用supabaseClient.auth.updateUser时触发Auth session missing!错误,相关现象如下:

  • 调用await supabaseClient.auth.getSession()返回:{ data: { session: null }, error: null }
  • 使用请求头中的JWT调用await supabaseClient.auth.getUser(req.headers.authorization)可获取用户信息,但无session对象:
{
  data: {
    user: {
      id: 'aa8c4b73-ba8d-4901-a768-1b48b72e334c',
      ...
    }
  },
  error: null
}

当前使用的处理代码:

export const resetPassword = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    await updatePasswordYupSchema.validate(req.body, {
      abortEarly: false,
    });
    const { data, error } = await supabaseClient.auth.updateUser({
      password: req.body.password,
    });
    if (error) throw error;
    res.status(200).json({ success: data });
  } catch (err) {
    if (err instanceof ValidationError) {
      const errorObject = yupError(err);
      next(errorObject);
    } else if (
      err instanceof AuthApiError ||
      err instanceof AuthSessionMissingError
    ) {
      console.log(err);
      customErrorHandler(err.status, err.message, res);
    } else {
      next(err);
    }
  }
};
解决方案

问题核心是supabaseClient.auth.updateUser()默认依赖客户端已存在的有效会话(Session),但当前场景是通过重置邮件中的token验证身份,并未在服务端Supabase客户端中建立会话。正确的处理流程如下:

  1. 从请求中提取重置邮件URL携带的token和type(重置密码的token类型固定为recovery)
  2. 通过supabaseClient.auth.verifyOtp()验证token合法性,同时完成密码更新(该方法验证通过后会自动创建会话)

修改后的代码示例

export const resetPassword = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    // 验证密码格式合法性
    await updatePasswordYupSchema.validate(req.body, { abortEarly: false });
    // 从URL参数中获取重置token和类型
    const { token, type = 'recovery' } = req.query;

    if (!token) {
      return customErrorHandler(400, '重置密码token不能为空', res);
    }

    // 验证重置token并同步设置新密码
    const { data: authData, error: authError } = await supabaseClient.auth.verifyOtp({
      token: token as string,
      type,
      password: req.body.password,
    });

    if (authError) throw authError;

    res.status(200).json({ success: authData });
  } catch (err) {
    if (err instanceof ValidationError) {
      const errorObject = yupError(err);
      next(errorObject);
    } else if (
      err instanceof AuthApiError ||
      err instanceof AuthSessionMissingError
    ) {
      console.log(err);
      customErrorHandler(err.status, err.message, res);
    } else {
      next(err);
    }
  }
};

补充说明

  • 重置密码邮件的链接会自动携带token和type参数,需前端将这两个参数传递至后端接口
  • 使用verifyOtp()并传入password参数,可在验证token的同时完成密码更新,无需单独调用updateUser()
  • 若需先验证token再单独更新密码,可在verifyOtp()执行后调用updateUser(),此时客户端已存在有效会话,不会再触发Auth session missing!错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:25:19