如何用 useForgotPassword 在 Refine 中实现用户忘记密码流程?
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
在 Refine 管理后台中,"忘记密码"流程由两部分组成:一个让用户提交邮箱的入口页面,以及authProvider里真正负责发送重置链接的forgotPassword方法。@refinedev/core提供的useForgotPasswordHook 是自定义页面处理这一流程的入口,它底层调用authProvider的forgotPassword方法。完成这个流程有两条路径:直接使用 Refine 默认的<AuthPage type="forgotPassword" />页面,或者用useForgotPassword自己实现表单页面。两条路径共用同一个前提——先实现并接入authProvider。
准备条件:实现并接入 authProvider
- 一个已安装
@refinedev/core的 Refine 应用。 - 把
authProvider作为 prop 传给<Refine />:
import { Refine } from "@refinedev/core"; import authProvider from "./auth-provider"; const App = () => { return <Refine authProvider={authProvider} />; };官方文档明确说明:authProvider不是 Refine 运行的必需项,但如果不提供,应用将不具备任何认证能力,"你无法使用任何 auth hooks 或 components",useForgotPassword也不例外。
第一步:在 authProvider 中实现 forgotPassword 方法
forgotPassword是authProvider的可选方法之一(其余可选方法包括register、updatePassword等;login、check、logout、onError为必需方法)。它的作用是把密码重置链接发送到用户邮箱,预期返回一个已 resolve 的 promise,类型为:
type SuccessNotificationResponse = { message: string; description?: string; }; type AuthActionResponse = { success: boolean; redirectTo?: string; error?: Error; [key: string]: unknown; successNotification?: SuccessNotificationResponse; };各字段的作用:
success:操作是否成功。为false时会显示错误通知。redirectTo:有值时,应用会跳转到该 URL。error:有值时,通知会显示其中的错误name和message。successNotification:提供时会显示成功通知。[key: string]:可以附带任意额外数据。
文档给出的示例实现如下:
import { AuthProvider } from "@refinedev/core"; const authProvider: AuthProvider = { // --- forgotPassword: async ({ email }) => { // send password reset link to the user's email address here // if request is successful return { success: true, redirectTo: "/login", }; // if request is not successful return { success: false, error: { name: "Forgot Password Error", message: "Email address does not exist", }, }; }, // --- };代码中的// ---代表authProvider上已有的其他方法(必需方法login、check、logout、onError等),你只需在现有对象中补上forgotPassword一项。email之外的参数不受限制,方法可以接收任意参数。
第二条路径(默认):使用
如果不需要自定义界面,Refine 提供了默认的忘记密码页面,手动处理整个流程。只需注册路由:
import { AuthPage } from "@refinedev/core"; // ... <Route path="/forgot-password" element={<AuthPage type="forgotPassword" />} />表单提交后,authProvider的forgotPassword方法会带着表单值(用户填写的email)被调用,与自定义页面走的是同一条后端逻辑。
与登录页的衔接由两个 prop 控制:
forgotPasswordLink:仅login类型可用,定义登录页上"忘记密码"链接的地址,默认值是"/forgot-password",也可以传一个自定义节点。loginLink:仅register和forgotPassword类型可用,定义页面上返回登录页的链接,默认值是"/login"。
另外,<AuthPage>的mutationVariablesprop 可以向authProvider方法传递表单之外的额外变量(所有类型均支持),例如mutationVariables={{ foo: "bar" }},方法内即可解构得到foo。
第三条路径(自定义):用 useForgotPassword 构建自己的页面
需要自定义界面时,用useForgotPasswordHook 处理提交流程。Hook 从@refinedev/core导入:
import { useForgotPassword } from "@refinedev/core"; type forgotPasswordVariables = { email: string; }; export const ForgotPasswordPage = () => { const { mutate: forgotPassword } = useForgotPassword<forgotPasswordVariables>(); const onSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const values = { email: e.currentTarget.email.value, }; forgotPassword(values); }; return ( <form onSubmit={onSubmit}> <label>Email</label> <input name="email" value="test@refine.com" /> <button type="submit">Submit</button> </form> ); };示例中的表单是文档给出的原生 HTML 简写,实际项目可以换成你使用的表单组件库。mutate可以接收任意对象作为 values,因为authProvider的forgotPassword方法对参数没有限制;如果想约束类型,通过泛型参数声明即可:
import { useForgotPassword } from "@refinedev/core"; const { mutate: forgotPassword } = useForgotPassword<{ email: string }>();控制提交后的跳转
有两种方式指定提交后的跳转目标。方式一:直接在forgotPassword方法里返回固定的redirectTo(如"/login")。方式二:调用mutate时传入redirectPath,由方法读取后再作为redirectTo返回,这样跳转目标可以按请求动态决定:
import { useForgotPassword } from "@refinedev/core"; const { mutate: forgotPassword } = useForgotPassword(); forgotPassword({ redirectPath: "/custom-url" });import type { AuthProvider } from "@refinedev/core"; const authProvider: AuthProvider = { // ... forgotPassword: async ({ redirectPath }) => { // ... return { success: true, redirectTo: redirectPath, successNotification: { message: "Password reset successful", description: "Your password has been successfully reset.", }, }; }, };结果判断与错误处理
useForgotPassword返回的是 react-queryuseMutation的结果,包含isSuccess、isError等状态属性;forgotPassword方法解析出的返回值作为查询结果中的data。提交后 Refine 会按data中的字段自动执行以下行为:
success: false:自动显示错误通知。如果返回了error,通知内容取其name和message;如果没有error,则显示通用错误(name为"Forgot Password Error")。- 提供了
successNotification:显示成功通知。 redirectTo有值:应用跳转到该 URL。
业务失败要在onSuccess回调里通过data.success判断:
import { useForgotPassword } from "@refinedev/core"; const { mutate: forgotPassword } = useForgotPassword(); forgotPassword( { email: "refine@example.com", }, { onSuccess: (data) => { if (!data.success) { // handle error } // handle success }, }, );这里有一个文档明确警告的坑:authProvider的方法永远返回已 resolve 的 promise,所以success为false时onError回调不会触发(它只在 promise 真正 reject 时触发)。如果你依赖onError来捕获"邮箱不存在"这类业务失败,是捕获不到的,必须在onSuccess里检查data.success。
一个需要留意的细节:Hook 文档给出的通用错误值是{ name: "Forgot Password Error", message: "Invalid credentials" },而当前仓库源码 useForgotPassword 实现 中未提供error时的默认描述是"Error while resetting password"。两处文案不一致,具体措辞以你安装的版本为准,不要写依赖该通用文案的断言。
边界与限制
- 没有
authProvider时,useForgotPassword与所有 auth hooks/components 都不可用,这是整个流程的硬性前提。 forgotPassword是可选方法:只打算使用默认<AuthPage>页面时同样需要它,因为页面提交后调用的就是它。- 默认页面已经完整处理了流程(包括成功/失败通知),Hook 只在自定义页面时才需要引入;两条路径按界面需求二选一即可,不需要同时存在。
相关文档
- useForgotPassword Hook
- Auth Provider 指南(含 forgotPassword 方法说明)
- AuthPage 组件(默认忘记密码页面)
- useForgotPassword 源码
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考