Flutter中结合Firebase实现密码与确认密码匹配验证的方法
解决密码与确认密码不匹配仍能存入Firebase的问题
当前代码的核心问题是确认密码的校验逻辑缺失匹配验证,只检查了非空和长度要求,导致两次密码不一致时表单仍能通过验证,进而触发Firebase的用户创建流程。以下是具体修复和优化方案:
1. 修复确认密码的校验逻辑
修改确认密码对应的TextFormField的validator,新增与密码字段的匹配校验:
Container( padding: const EdgeInsets.only(right: 42), child: TextFormField( controller: _confirmPasswordController, key: const ValueKey('ConfirmPassword'), // 修正key,避免和密码字段重复 validator: (value) { if (value!.isEmpty || value.length < 7) { return '请输入有效的密码'; } // 新增:对比密码与确认密码是否一致 if (value != _passwordController.text) { return '两次输入的密码不匹配'; } return null; }, keyboardType: TextInputType.visiblePassword, // 密码输入场景更合理的类型 focusNode: _confirmPasswordFocusNode, autovalidateMode: AutovalidateMode.onUserInteraction, onEditingComplete: _submitForm, decoration: const InputDecoration( hintText: '确认密码', icon: Image( image: AssetImage('assets/images/Icon feather-lock.png'), ), ), onSaved: (value) { _confirmPasswordController.text = value!; }), ),
2. (可选但推荐)在提交方法中增加二次校验
为避免前端验证异常,在_submitForm方法的isValid判断后,再补一层密码匹配校验:
void _submitForm() async { final isValid = _formKey.currentState!.validate(); FocusScope.of(context).unfocus(); var now = DateTime.now(); var formattedDate = "${now.day}-${now.month}-${now.year}"; if (isValid) { // 新增二次校验:确保密码与确认密码一致 if (_passwordController.text != _confirmPasswordController.text) { _globalMethods.authErrorHandle('两次输入的密码不匹配', context); return; } _formKey.currentState!.save(); try { setState(() { _isLoading = true; }); await _auth.createUserWithEmailAndPassword( email: _emailAddress.text, password: _passwordController.text); final User? user = _auth.currentUser; final _uid = user!.uid; user.reload(); await FirebaseFirestore.instance.collection('users').doc(_uid).set({ 'id': _uid, 'username': _username, 'email': _emailAddress.text, // 修正:取输入框文本而非controller对象 'joinedAt': formattedDate, 'createdAt': Timestamp.now(), // 移除明文密码存储:Firebase Auth已管理密码,无需存明文到Firestore }); Navigator.of(context) .push(MaterialPageRoute(builder: (context) => const SignInPage())); } catch (error) { _globalMethods.authErrorHandle(error.toString(), context); print('error occured ${error.toString()}'); } finally { setState(() { _isLoading = false; }); } } }
3. 关键安全优化:不要存储明文密码
当前代码将明文密码存入Firestore是严重的安全风险,Firebase Auth已经负责用户密码的管理,完全不需要自己存储明文密码,直接删除'Password': _passwordController.text这一行即可。
4. 日期格式化简化
原来的日期处理代码可以简化,无需先转字符串再解析:
// 替换原日期处理代码 var now = DateTime.now(); var formattedDate = "${now.day}-${now.month}-${now.year}";
内容的提问来源于stack exchange,提问作者Muhammad Sufyan
相关产品推荐
相关产品推荐

