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

如何在Supabase中预验证重置密码Token,无效时跳转登录页?

Supabase重置密码页面前置Token验证实现方案

核心思路

在重置密码页面渲染前,从URL提取Token,调用Supabase官方验证接口校验Token有效性:

  • 验证通过:正常展示重置密码表单
  • 验证失败/无Token:立即跳转至登录页面

具体实现步骤

  1. 提取URL中的Token:从页面URL的查询参数中获取token(Supabase默认重置密码链接的参数名为token)。
  2. 调用Supabase Token验证接口:使用Supabase Auth模块的verifyOtp方法,指定type: 'recovery'(重置密码Token属于恢复类OTP),验证Token的有效性。
  3. 根据验证结果处理页面逻辑:无Token/验证失败直接跳转登录页;验证通过则渲染重置密码表单,后续提交新密码时可直接调用updateUser接口(验证通过后Supabase会生成临时会话)。

代码示例

React 前端验证

import { useEffect, useState } from 'react';
import { supabase } from '../utils/supabaseClient';
import { useNavigate } from 'react-router-dom';

const ResetPasswordPage = () => {
  const navigate = useNavigate();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const checkTokenValidity = async () => {
      const params = new URLSearchParams(window.location.search);
      const token = params.get('token');

      if (!token) {
        navigate('/login');
        return;
      }

      try {
        const { error } = await supabase.auth.verifyOtp({
          token,
          type: 'recovery'
        });

        if (error) navigate('/login');
      } catch (err) {
        console.error('Token验证失败:', err);
        navigate('/login');
      } finally {
        setLoading(false);
      }
    };

    checkTokenValidity();
  }, [navigate]);

  if (loading) return <div>加载中...</div>;

  return (
    <div className="reset-password-form">
      <h2>重置密码</h2>
      <form onSubmit={async (e) => {
        e.preventDefault();
        const newPassword = e.target.password.value;
        const { error } = await supabase.auth.updateUser({ password: newPassword });
        
        if (error) alert('密码重置失败:' + error.message);
        else {
          alert('密码重置成功');
          navigate('/login');
        }
      }}>
        <input type="password" name="password" placeholder="设置新密码" required />
        <button type="submit">确认重置</button>
      </form>
    </div>
  );
};

export default ResetPasswordPage;

纯 JavaScript 验证

document.addEventListener('DOMContentLoaded', async () => {
  const params = new URLSearchParams(window.location.search);
  const token = params.get('token');

  if (!token) {
    window.location.href = '/login.html';
    return;
  }

  try {
    const { error } = await supabase.auth.verifyOtp({
      token,
      type: 'recovery'
    });

    if (error) {
      window.location.href = '/login.html';
    } else {
      // 显示重置密码表单
      document.getElementById('reset-form').style.display = 'block';
    }
  } catch (err) {
    console.error('Token验证出错:', err);
    window.location.href = '/login.html';
  }
});

Next.js 服务器端验证(更安全)

// pages/reset-password.js
import { supabase } from '../utils/supabaseClient';
import { useRouter } from 'next/router';

export async function getServerSideProps(context) {
  const { token } = context.query;

  if (!token) {
    return { redirect: { destination: '/login', permanent: false } };
  }

  try {
    const { error } = await supabase.auth.verifyOtp({ token, type: 'recovery' });
    if (error) return { redirect: { destination: '/login', permanent: false } };
  } catch (err) {
    return { redirect: { destination: '/login', permanent: false } };
  }

  return { props: { token } };
}

export default function ResetPasswordPage() {
  const router = useRouter();

  const handleSubmit = async (e) => {
    e.preventDefault();
    const newPassword = e.target.password.value;
    const { error } = await supabase.auth.updateUser({ password: newPassword });
    
    if (error) alert('密码重置失败:' + error.message);
    else {
      alert('密码重置成功');
      router.push('/login');
    }
  };

  return (
    <div>
      <h2>重置密码</h2>
      <form onSubmit={handleSubmit}>
        <input type="password" name="password" placeholder="设置新密码" required />
        <button type="submit">确认重置</button>
      </form>
    </div>
  );
}

注意事项

  • 确保Supabase客户端已正确初始化,包含Auth模块配置
  • verifyOtp的type必须设为recovery,否则无法正确验证重置密码Token
  • 验证过程中显示加载状态,避免用户重复操作
  • 跳转登录前可提示模糊错误信息(如“链接已失效,请重新申请重置密码”),不要泄露Token具体错误细节
  • Supabase重置密码Token默认有效期为1小时,验证时会自动判断是否过期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:40:04