Flutter接入Firebase Auth时邮箱未注册/密码错误仍可登录问题排查
问题原因分析
你的认证逻辑核心问题是没有对Firebase Auth接口抛出的异常做捕获处理:
Firebase Auth的signInWithEmailAndPassword、createUserWithEmailAndPassword这类方法,在遇到邮箱未注册、密码错误、邮箱格式非法、账号被封禁等异常场景时,会主动抛出对应类型的FirebaseAuthException。你现有的代码完全没有做异常捕获,只要上层调用时没有等待异步执行完成、或者没有捕获抛出的异常,就会直接跳过错误分支,误判为登录成功。
修复方案
1. 改造认证方法,新增异常捕获逻辑
修改Authentication.dart中的logIntoAccount、createAccount方法,增加异常捕获分支,返回明确的执行结果:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:google_sign_in/google_sign_in.dart'; class Authentication with ChangeNotifier { final FirebaseAuth firebaseAuth = FirebaseAuth.instance; final GoogleSignIn googleSignIn = GoogleSignIn(); String? userUid; String? get getUserUid => userUid; // 改造后的邮箱登录方法 Future<Object> logIntoAccount(String email, String password) async { try { UserCredential userCredential = await firebaseAuth .signInWithEmailAndPassword(email: email, password: password); User? user = userCredential.user; if(user != null) { userUid = user.uid; debugPrint(userUid); notifyListeners(); return true; } return "获取用户信息失败"; } on FirebaseAuthException catch (e) { // 匹配不同错误码返回对应提示 switch(e.code) { case 'user-not-found': return "该邮箱未注册"; case 'wrong-password': return "输入的密码错误"; case 'invalid-email': return "邮箱格式不合法"; case 'user-disabled': return "该账号已被封禁"; default: return "登录失败:${e.message}"; } } catch (e) { return "未知错误:$e"; } } // 改造后的账号注册方法 Future<Object> createAccount(String email, String password) async { try { UserCredential userCredential = await firebaseAuth .createUserWithEmailAndPassword(email: email, password: password); User? user = userCredential.user; if(user != null) { userUid = user.uid; debugPrint('Created account Uid => $userUid'); notifyListeners(); return true; } return "获取用户信息失败"; } on FirebaseAuthException catch (e) { switch(e.code) { case 'email-already-in-use': return "该邮箱已被注册"; case 'invalid-email': return "邮箱格式不合法"; case 'operation-not-allowed': return "邮箱登录功能未开启"; case 'weak-password': return "密码强度过低"; default: return "注册失败:${e.message}"; } } catch (e) { return "未知错误:$e"; } } Future logOutViaEmail() { userUid = null; notifyListeners(); return firebaseAuth.signOut(); } Future signInWithGoogle() async { final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); if(googleSignInAccount == null) return "用户取消了Google登录"; final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication; final AuthCredential authCredential = GoogleAuthProvider.credential( accessToken: googleSignInAuthentication.accessToken, idToken: googleSignInAuthentication.idToken); try { final UserCredential userCredential = await firebaseAuth.signInWithCredential(authCredential); final User? user = userCredential.user; if(user == null) return "获取Google用户信息失败"; userUid = user.uid; debugPrint('Google User Uid => $userUid'); notifyListeners(); return true; } on FirebaseAuthException catch (e) { return "Google登录失败:${e.message}"; } } Future signOutWithGoogle() async { userUid = null; notifyListeners(); return googleSignIn.signOut(); } }
2. 上层调用注意事项
调用异步认证方法时必须添加await,等方法执行完成后再判断结果,禁止调用后直接走登录成功逻辑,示例如下:
// 错误写法:不等异步执行完成就跳转,不管成功失败都认为登录成功 auth.logIntoAccount(inputEmail, inputPassword); Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage())); // 正确写法:等待执行结果,判断成功后再跳转 var loginResult = await auth.logIntoAccount(inputEmail, inputPassword); if(loginResult == true) { // 登录成功跳转首页 if(mounted) { Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage())); } } else { // 登录失败弹出错误提示 if(mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(loginResult.toString())) ); } }
内容的提问来源于stack exchange,提问作者Anoop Janakar
相关产品推荐
相关产品推荐

