简体   繁体   English

使用 Google 问题进行 Firebase 身份验证

[英]Firebase Authentication with Google issue

I have been using Firebase Authentication in my app, and have noticed an issue with a particular use case.我一直在我的应用程序中使用 Firebase 身份验证,并注意到一个特定用例的问题。

I have enabled account linking sign up flow for my app, and thus I can attach multiple providers associated with a single email address.我为我的应用程序启用了帐户链接注册流程,因此我可以附加与单个电子邮件地址关联的多个提供商。

Scenario 1: (Works fine)场景 1:(工作正常)

The user has signed up with Google initially and sometime later, signs in in with Facebook or registers with email and password.用户最初与 Google 注册,稍后使用 Facebook 登录或使用电子邮件和密码注册。

The account linking works fine and Facebook and/or Email is added in the provider list.帐户链接工作正常,并且 Facebook 和/或电子邮件已添加到提供商列表中。

So, I can have 2 or 3 providers for the email, Google (initially), Facebook and Password (after that).因此,我可以有 2 或 3 个电子邮件提供商,Google(最初)、Facebook 和密码(之后)。

Scenario 2: (The bug)场景2:(错误)

The user has signed up with Facebook and/or Email initially and later signs in with Google, now the account linking doesn't work.用户最初使用 Facebook 和/或电子邮件注册,后来使用 Google 登录,现在帐户链接不起作用。 Google replaces the previous providers present.谷歌替换了以前的提供者。

Account linking fails , and I just have Google as the sole provider associated with the email address and the others are gone.帐户链接失败,我只是将 Google 作为与电子邮件地址关联的唯一提供商,而其他提供商都消失了。

In the second scenario, while signing in with Google , it should fail and throw FirebaseAuthCollisionException but it doesn't and succeeds.在第二种情况下,当使用 Google 登录时,它应该失败并抛出FirebaseAuthCollisionException但它没有成功。 This is the main issue.这是主要问题。

I can't paste the whole code here, but just a snippet for sure.我不能在这里粘贴整个代码,但肯定只是一个片段。

firebaseAuth
                        .signInWithCredential(credential)
                        .addOnFailureListener(exception -> {
                            if (exception instanceof FirebaseAuthUserCollisionException) {
                                mCredentialToLinkWith = credential;
                                if (mProviderList.size() == 1) {
                                    if (mProviderList.contains(EmailAuthProvider.PROVIDER_ID)) {
                                        mRegisterProviderPresenter.linkWithEmailProvider(credential, email);
                                    } else {
                                        linkProviderAccounts(email, AuthenticationHelper.getProviderToLinkAccounts(mWeakActivity, mProviderList));
                                    }
                                } else {
                                    linkProviderAccounts(email, AuthenticationHelper.getProviderToLinkAccounts(mWeakActivity, mProviderList));
                                }
                            } else {
                                Timber.d("Failed in signInWithCredential and unexpected exception %s", exception.getLocalizedMessage());
                                mRegisterProviderPresenter.onRegistrationFailed(new ErrorBundle(ErrorBundle.FIREBASE_ERROR, exception.getLocalizedMessage()));
                            }
                        })
                        .addOnSuccessListener(authResult -> {
                            Timber.d("Success: signInCred");
                            FirebaseUser firebaseUser = authResult.getUser();
                            /**
                             * Store the user details only for first time registration
                             * and not while acc linking
                             */
                            storeUserCredentials(firebaseUser);
                            AuthenticationHelper.logUserDetails(firebaseUser);
                            mRegisterProviderPresenter.onRegistrationSuccess(mAlreadyRegistered);

                        });

Hope someone can come up with some help.希望有人能提出一些帮助。

Facebook is a social identity provider and it doesn't own the emails. Facebook 是一个社交身份提供商,它不拥有电子邮件。 If an email is hacked, Facebook can't detect it and disable the account registered by this email.如果电子邮件被黑客入侵,Facebook 无法检测到它并禁用通过该电子邮件注册的帐户。 While Google is an email provider, its accounts are considered to be more secure.虽然 Google 是电子邮件提供商,但其帐户被认为更安全。

Based on this theory, scenario 2 is different from 1. In scenario 1, the user has proved the ownership of this email by signing with Google first.基于这个理论,场景2不同于1。在场景1中,用户首先通过谷歌签名证明了这封电子邮件的所有权。 So the user is allowed to add Facebook account using the same email.因此,允许用户使用同一电子邮件添加 Facebook 帐户。 In scenario 2, Facebook sign in happens first and this provider record is untrusted, so it's removed when user signs in with another trusted provider.在场景 2 中,首先登录 Facebook,并且此提供商记录不受信任,因此当用户通过另一个受信任的提供商登录时,它会被删除。

Your code behavior is correct in both scenarios.您的代码行为在这两种情况下都是正确的。

I faced the same issue and this is a supplemental answer for the question in the comment ie我遇到了同样的问题,这是评论中问题的补充答案,即

Why is that after initially registering with a email & password, and then with Google, Google still replaces it?

I did some more exploration and found the answer here .我做了一些更多的探索并在这里找到了答案。

Pasting the relevant snippet.粘贴相关代码段。

If there is an existing account with the same email address but created with non-trusted credentials (eg non-trusted provider or password), the previous credentials are removed for security reason.如果存在具有相同电子邮件地址但使用不受信任的凭据(例如不受信任的提供商或密码)创建的现有帐户,则出于安全原因删除先前的凭据。 A phisher (who is not the email address owner) might create the initial account - removing the initial credential would prevent the phisher from accessing the account afterwards.网络钓鱼者(不是电子邮件地址所有者)可能会创建初始帐户 - 删除初始凭据将阻止网络钓鱼者随后访问该帐户。

The solution to handle this, ie to prevent Google from replacing the existing provider with Google, is to verify the email of the user.处理此问题的解决方案,即防止 Google 用 Google 替换现有提供商,是验证用户的电子邮件。

So, after the user creates the account with email & password, or logs in with Facebook (or any other provider), send an email verification link to the user.因此,在用户使用电子邮件和密码创建帐户或使用 Facebook(或任何其他提供商)登录后,向用户发送电子邮件验证链接。

After the user verifies his/her email, then the subsequent Sign-in with Google will NOT replace the existing providers.用户验证他/她的电子邮件后,随后的Sign-in with Google将不会替换现有的提供商。

暂时只使用电子邮件和密码身份验证或第 3 方插件目前尚无解决方案

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

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