新用户未验证邮箱时,应用关闭重启直接进入主页问题求助
修复未验证邮箱用户绕过登录页的漏洞
这个问题我之前帮好几个开发者排查过,核心原因就是App冷启动时只检查了Firebase用户是否存在,却没验证用户的邮箱状态——Firebase在用户注册后会把未验证的用户信息缓存到本地,所以杀后台重启时,Auth.auth().currentUser会存在,但用户其实还没完成邮箱验证,这就导致了绕过登录页的漏洞。
下面是具体的修复步骤:
1. 修正App启动时的用户校验逻辑
不管你用的是SceneDelegate还是AppDelegate,在App初始化的入口方法里,必须同时检查用户存在性和邮箱验证状态:
// 以SceneDelegate为例,在scene(_:willConnectTo:options:)方法中 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window // 检查当前用户 if let currentUser = Auth.auth().currentUser { // 关键:必须验证邮箱是否已通过 if currentUser.isEmailVerified { // 已验证,正常进入主页 let homeVC = HomeViewController() window.rootViewController = UINavigationController(rootViewController: homeVC) } else { // 未验证,强制跳转登录页并提示用户验证邮箱 let loginVC = LoginViewController() window.rootViewController = UINavigationController(rootViewController: loginVC) showVerificationPrompt() // 自定义的提示弹窗方法 } } else { // 无登录用户,直接进入登录页 let loginVC = LoginViewController() window.rootViewController = UINavigationController(rootViewController: loginVC) } window.makeKeyAndVisible() }
2. 实时监听用户验证状态变化
用户可能在App外完成邮箱验证(比如用系统邮件App点击验证链接),这时候回到App需要刷新用户状态,避免未验证用户停留在主页:
// 在主页ViewController的viewDidAppear方法中 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) guard let user = Auth.auth().currentUser else { return } // 刷新Firebase用户信息(本地缓存可能未同步验证状态) user.reload { [weak self] error in guard let self = self else { return } if let error = error { print("刷新用户信息失败:\(error.localizedDescription)") return } if !user.isEmailVerified { // 未验证,强制跳转回登录页 let loginVC = LoginViewController() self.navigationController?.setViewControllers([loginVC], animated: true) self.showVerificationPrompt() } } }
3. 补充边界场景校验
为了彻底堵上漏洞,建议在主页的初始化方法(比如viewDidLoad)也加一层校验,防止用户通过其他路由跳转进入主页:
override func viewDidLoad() { super.viewDidLoad() guard let user = Auth.auth().currentUser, user.isEmailVerified else { // 未验证,直接跳转登录页 let loginVC = LoginViewController() navigationController?.setViewControllers([loginVC], animated: false) return } // 正常加载主页内容 }
核心要点就是:永远不要只通过currentUser != nil来判断用户是否有权限进入主页,必须同时校验isEmailVerified属性,而且要注意Firebase本地缓存的时效性,必要时调用user.reload()同步最新状态。
内容的提问来源于stack exchange,提问作者Wahaj Uddin
相关产品推荐
相关产品推荐

