Flutter集成Firebase实现APP内忘记密码重置(含OTP验证)
Flutter集成Firebase实现密码重置功能
一、基于OTP邮箱验证后的密码重置流程
1. 验证OTP并跳转至新密码页面
在现有邮箱OTP验证页面,用户输入OTP完成验证后,通过Firebase Auth获取已验证的用户实例,随后跳转至新密码输入页面:
final auth = FirebaseAuth.instance; final userEmail = "user@example.com"; // 用户输入的邮箱 final otpLink = "otp_link_received"; // 或用户输入的OTP对应的验证链接 try { // 验证邮箱OTP并获取用户凭证 final userCredential = await auth.signInWithEmailLink( email: userEmail, emailLink: otpLink, ); // 验证成功,跳转至新密码设置页 if (mounted) { Navigator.push( context, MaterialPageRoute( builder: (_) => SetNewPasswordPage(user: userCredential.user!), ), ); } } on FirebaseAuthException catch (e) { // 处理验证失败场景(OTP错误、过期等) ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.message ?? "OTP验证失败")), ); }
2. 新密码输入与重置实现
创建新密码输入页面,接收已验证的用户实例,输入新密码后调用Firebase的updatePassword方法完成重置:
class SetNewPasswordPage extends StatefulWidget { final User user; const SetNewPasswordPage({super.key, required this.user}); @override State<SetNewPasswordPage> createState() => _SetNewPasswordPageState(); } class _SetNewPasswordPageState extends State<SetNewPasswordPage> { final _newPasswordCtrl = TextEditingController(); final _confirmPasswordCtrl = TextEditingController(); bool _isLoading = false; Future<void> _resetPassword() async { // 校验密码格式与一致性 if (_newPasswordCtrl.text != _confirmPasswordCtrl.text) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("两次输入的密码不一致")), ); return; } if (_newPasswordCtrl.text.length < 6) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("密码长度至少为6位")), ); return; } setState(() => _isLoading = true); try { // 更新用户密码 await widget.user.updatePassword(_newPasswordCtrl.text); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("密码重置成功")), ); // 跳转至登录页或首页 Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const LoginPage())); } on FirebaseAuthException catch (e) { String errorMsg; switch (e.code) { case "weak-password": errorMsg = "密码强度不足,请设置更复杂的密码"; break; case "requires-recent-login": errorMsg = "用户身份验证已过期,请重新验证后再尝试"; break; default: errorMsg = e.message ?? "密码重置失败"; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(errorMsg)), ); } finally { setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("设置新密码")), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: _newPasswordCtrl, obscureText: true, decoration: const InputDecoration( labelText: "新密码", hintText: "请输入不少于6位的密码", ), ), const SizedBox(height: 16), TextField( controller: _confirmPasswordCtrl, obscureText: true, decoration: const InputDecoration(labelText: "确认新密码"), ), const SizedBox(height: 24), ElevatedButton( onPressed: _isLoading ? null : _resetPassword, child: _isLoading ? const CircularProgressIndicator(color: Colors.white) : const Text("确认重置密码"), ), ], ), ), ); } }
二、无需发送验证邮件直接更新密码(2025年7月更新)
Firebase Auth现已支持无需发送验证邮件即可更新密码,前提是用户已完成身份验证(如OTP验证、近期登录等)。官方文档相关内容翻译如下:
设置用户密码
你可以更新已登录用户的密码。为避免安全风险,调用此方法前用户必须完成近期身份验证(如登录、OTP验证等)。
要更新用户密码,直接调用用户实例的
updatePassword方法并传入新密码:final currentUser = FirebaseAuth.instance.currentUser; final newPassword = "YourNewStrongPassword123"; if (currentUser != null) { try { await currentUser.updatePassword(newPassword); print("密码更新成功"); } on FirebaseAuthException catch (e) { print(e.message); // 处理错误:如密码强度不足、身份验证过期等 } }若调用时用户未满足"近期身份验证"要求,会抛出
requires-recent-login错误。此时需重新验证用户身份(如邮箱OTP、短信验证),之后再调用updatePassword方法。
内容的提问来源于stack exchange,提问作者Muhammad Muddassar
相关产品推荐
相关产品推荐

