繁体   English   中英

Firebase Auth 链接提供商 Google 登录问题?

[英]Firebase Auth link provider Google sign in issue?

第一次使用 Gmail 和密码注册时,firebase 正确保存了凭据。 但是下一次,我使用 Firebase Google 身份验证登录,使用我在注册时提供的相同 Gmail,凭据在 firebase 帐户中被覆盖。 覆盖凭据后,我们无法使用该注册凭据登录。 谁能解释如何实现这一目标?

使用 Gmail 和密码注册

谷歌认证

发生了什么

在第一个屏幕截图中,您使用 Firebase 的电子邮件+密码提供商登录。 虽然这是一种有效的登录方法,但这意味着任何人都可以输入该 email 地址,即使他们实际上无法访问该 gmail 地址的 Google 帐户。

这里不存在安全风险,但是我们可以对 email 地址的值的信任度较低。 由于这个原因,帐户的emailVerified属性被标记为false ,您通常需要要求用户在允许他们继续之前验证他们的 email 地址。


在第二个屏幕截图中,用户使用相同的 email 地址登录,但现在使用 Firebase 的google.com提供商登录。 这意味着 Google 现在已经验证用户可以访问该帐户的底层 gmail 地址。 由于google.com提供程序是@gmail.com帐户的受信任提供程序,因此系统将替换以前的帐户。


另见:

你可以做什么

您通常希望防止多个用户使用相同的 email 地址进行注册。 为此,您需要将 Firebase 配置为在控制台中每个 email 地址只允许一个帐户,然后使用帐户链接,以便合并您方案中的两个(电子邮件+密码和 google.com)帐户。

您是否在第一次登录尝试时验证了 email 或电话号码? 如果没有,这是设计使然:

登录完成后,任何以前未经验证的登录机制都将从用户中删除,任何现有会话都将失效。 例如,如果有人之前使用相同的 email 和密码创建了一个未经验证的帐户,则该用户的密码将被删除,以防止声称拥有所有权并创建该未经验证帐户的冒充者使用未经验证的 email 和密码再次登录。

资源

我刚刚遇到了这个问题,这里有一个更长更深入的描述。 (情况经常变化,2021 年 11 月确实如此。)

简短版:正如@Frank van Puffelen所说,这是设计使然。 问题是email+password通常不是受信任的提供商,因此像Google Authentication这样的受信任提供商会覆盖该方法。 它默默地这样做(我认为,没有检查GoogleSignInAuthentication object 中的每个字段。)

它会在密码重置后自动链接。 因此,一种选择是让用户通过_firebaseAuth.sendPasswordResetEmail(email: email);设置他们的密码。

另外:我不建议像其他人建议的那样关闭One account per email address 看到最后的原因。

默认情况下的“奇怪”行为One account per email address

在我的应用程序中,会发生以下情况。

  1. 通过电子邮件+密码注册 testUser1234@gmail.com。
  2. 使用 provider=Email/Password 为c_example_account@gmail.com创建一个帐户,如 firebaseAuth 仪表板中的信封/邮件图标所示。 初始 FirebaseAuth 仪表板的图片
  3. 注销并通过 Google 重新登录登录c_example_account@gmail.com
  4. 提供者已更改。 旧提供商是电子邮件/密码图标(信封)。 新的提供商是 Google 图标。 (如屏幕截图中的底部三个帐户)。 另请注意, User UID是相同的。 因此,与该User UID相关联的任何内容仍然可以。
  5. 由于c_example_account@gmail.com的电子邮件/密码登录方法 (AKA) 提供程序已删除,因此用户无法再使用该方法登录。 重要提示:这是静默完成的,用户不会收到任何电子邮件/密码登录已删除的通知。
  6. 尝试使用电子邮件/密码登录将导致Incorrect Password 注意:人们可能期望它会给出一个错误,比如“只有 Google 登录可用”,但事实并非如此。 将此与 email 不存在时(如尝试垃圾@123457.com)进行对比,后者有错误Email is not found...

现在,它变得有点奇怪......

  1. 假设用户使用“重置密码”就像这样被调用
  Future<void> resetPassword(String email) async {
    await _firebaseAuth.sendPasswordResetEmail(email: email);
  }
  1. 然后, firebaseAuth控制台对相同的 USER UID 有两种方法。 请参阅屏幕截图中的第二行和第三行。 密码重置后的双重登录方式
  2. 现在,这两种方法都被允许。 不同的是,第一次是createUserWithEmailAndPassword()之类的
      await _firebaseAuth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );

...但这次它是通过“重置”事件创建的

  Future<void> resetPassword(String email) async {
    await _firebaseAuth.sendPasswordResetEmail(email: email);
  }

...通过由 firebaseAuth firebaseAuth service发送的 email 提供了一个链接。 在这种情况下,验证了 email。

  1. 回顾:现在这两种方法都有效。 这两种方法是 (1) Google 身份验证和 (2) 电子邮件/密码。 在谷歌的说法中,这些帐户已被链接: https://firebase.google.com/docs/auth/android/account-linking 链接意味着一个User UID ,多种登录方式

为什么用两种不同的方法创建电子邮件/密码时会出现奇怪的行为?

~~我在firebaseAuth中找不到这个记录,可能是因为我看起来不够努力,或者可能因为这不是一个常见的问题。 ~~ 此行为记录在2020 年 4 月的问题评论中

我认为原因是因为_firebaseAuth.createUserWithEmailAndPassword版本具有未经验证的 email 因此,假设电子邮件+密码组合不存在,任何人都可以为其他任何人创建帐户。 例如,我可以使用用户名president@whitehouse.gov创建一个帐户,而实际上没有访问该 email 的权限。 如果实际的总统通过Google Authentication登录,那么我就可以伪造访问该用户的信息。 除了聪明的谷歌工程师决定,经过验证的Google Authentication然后触发删除未经验证Email/Password提供程序/帐户实例。

简而言之,逻辑可能是:已验证的胜过/未验证的覆盖。 请参阅https://firebase.google.com/docs/auth/users#verified_email_addresses

同样,对于电子邮件/密码,这些都没有明确记录。 但它在文档中有所暗示,例如Facebook Auth帐户是否被Google Auth覆盖。


已验证 Email 详细信息的快照

复制自: https://firebase.google.com/docs/auth/users#verified_email_addresses

由我添加的粗体,用于强调

在某些情况下,当用户使用相同的 email 地址登录不同的提供商时,Firebase 将自动链接帐户。 但是,这只有在满足特定标准时才会发生。 要了解原因,请考虑以下情况:用户使用 @gmail.com 帐户使用 Google 登录,而恶意行为者使用相同的 @gmail.com 地址创建帐户,但通过 ZD85544FCE402C7A2A936A48078ED 登录。 如果这两个帐户被自动链接,恶意行为者将获得对用户帐户的访问权限。

以下情况描述了我们何时自动关联帐户以及何时抛出需要用户或开发人员操作的错误:

  • 用户使用不受信任的提供商登录,然后使用具有相同 email 的另一个不受信任的提供商登录(例如,Facebook 后跟 GitHub)。 这会引发需要帐户链接的错误。
  • 用户使用受信任的提供商登录,然后使用具有相同 email 的不受信任的提供商登录(例如,Google 后跟 Facebook)。 这会引发需要帐户链接的错误。
  • 用户使用不受信任的提供商登录,然后使用具有相同 email 的受信任提供商登录(例如,Facebook 后跟 Google)。 受信任的提供者覆盖不受信任的提供者 如果用户尝试使用 Facebook 再次登录,则会导致需要帐户链接的错误。
  • 用户使用受信任的提供商登录,然后使用具有相同 email 的不同受信任提供商登录(例如,Apple 后跟 Google)。 两个提供者将无错误地链接。

您可以手动设置 email 并使用管理员 SDK 进行验证,但我们建议您仅在知道用户确实拥有 email 时才这样做。


为什么不关闭One account per email address

默认情况下,@ Deva所写的One account per email address处于活动状态。 但是,取消选中这意味着同一个 email 有两个不同的帐户( User UIDs )。 一种通过Email/Password ,另一种通过Google Authentication 他们将在Firebase Auth中有单独的用户 UID ,这可能会让您感到困惑。 此外,如果您在您的应用程序中手动链接两个User UIDs ,这会产生一个安全漏洞:有人可以在没有 email 验证的情况下创建一个帐户来访问现有帐户。 所以不要那样做。


相关 StackOverflow 问题和链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM