具有 Google 问题的 Firebase 身份验证
Firebase Authentication with Google issue
我一直在我的应用程序中使用 Firebase 身份验证,并注意到一个特定用例的问题。
我为我的应用程序启用了帐户链接注册流程,因此我可以附加与单个电子邮件地址关联的多个提供商。
场景 1:(工作正常)
用户最初和之后使用 Google 注册,使用 Facebook 登录或使用电子邮件和密码注册。
帐户链接工作正常和 Facebook and/or电子邮件已添加到提供商列表中。
所以,我可以有 2 或 3 个提供商提供电子邮件,Google(最初),Facebook 和密码(之后)。
场景 2:(错误)
用户已使用 Facebook and/or 注册,最初使用电子邮件注册,后来使用 Google 注册,现在帐户链接不起作用。 Google 替换现有的提供者。
帐户链接失败,我只有 Google 作为与电子邮件地址相关联的唯一提供商,其他提供商都消失了。
在第二种情况下,在使用 Google 登录时,它应该会失败并抛出 FirebaseAuthCollisionException
但它不会成功。 这是主要问题。
我不能在这里粘贴整个代码,但肯定只是一个片段。
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);
});
希望有人能提供一些帮助。
Facebook 是一家社交身份提供商,它不拥有电子邮件。如果电子邮件被黑客入侵,Facebook 无法检测到它并禁用通过该电子邮件注册的帐户。虽然 Google 是电子邮件提供商,但其帐户被认为更安全。
基于此理论,场景 2 不同于场景 1。在场景 1 中,用户首先通过 Google 签名证明了该电子邮件的所有权。因此允许用户使用相同的电子邮件添加 Facebook 帐户。在场景 2 中,Facebook 登录首先发生,并且此提供者记录不受信任,因此当用户使用另一个受信任的提供者登录时,它会被删除。
您的代码行为在这两种情况下都是正确的。
暂时使用邮箱和密码验证或使用第三方插件目前没有解决方案
我遇到了同样的问题,这是对评论中问题的补充回答,即
Why is that after initially registering with a email & password, and then with Google, Google still replaces it?
我做了更多探索并找到了答案 here。
正在粘贴相关代码段。
If there is an existing account with the same email address but created with non-trusted credentials (e.g. 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.
处理此问题的解决方案,即防止 Google 将现有提供商替换为 Google,是验证用户的电子邮件。
因此,在用户使用电子邮件和密码创建帐户或使用 Facebook(或任何其他提供商)登录后,向用户发送电子邮件验证 link。
用户验证 his/her 电子邮件后,随后的 Sign-in with Google
将不会替换现有提供商。
我一直在我的应用程序中使用 Firebase 身份验证,并注意到一个特定用例的问题。
我为我的应用程序启用了帐户链接注册流程,因此我可以附加与单个电子邮件地址关联的多个提供商。
场景 1:(工作正常)
用户最初和之后使用 Google 注册,使用 Facebook 登录或使用电子邮件和密码注册。
帐户链接工作正常和 Facebook and/or电子邮件已添加到提供商列表中。
所以,我可以有 2 或 3 个提供商提供电子邮件,Google(最初),Facebook 和密码(之后)。
场景 2:(错误)
用户已使用 Facebook and/or 注册,最初使用电子邮件注册,后来使用 Google 注册,现在帐户链接不起作用。 Google 替换现有的提供者。
帐户链接失败,我只有 Google 作为与电子邮件地址相关联的唯一提供商,其他提供商都消失了。
在第二种情况下,在使用 Google 登录时,它应该会失败并抛出 FirebaseAuthCollisionException
但它不会成功。 这是主要问题。
我不能在这里粘贴整个代码,但肯定只是一个片段。
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);
});
希望有人能提供一些帮助。
Facebook 是一家社交身份提供商,它不拥有电子邮件。如果电子邮件被黑客入侵,Facebook 无法检测到它并禁用通过该电子邮件注册的帐户。虽然 Google 是电子邮件提供商,但其帐户被认为更安全。
基于此理论,场景 2 不同于场景 1。在场景 1 中,用户首先通过 Google 签名证明了该电子邮件的所有权。因此允许用户使用相同的电子邮件添加 Facebook 帐户。在场景 2 中,Facebook 登录首先发生,并且此提供者记录不受信任,因此当用户使用另一个受信任的提供者登录时,它会被删除。
您的代码行为在这两种情况下都是正确的。
暂时使用邮箱和密码验证或使用第三方插件目前没有解决方案
我遇到了同样的问题,这是对评论中问题的补充回答,即
Why is that after initially registering with a email & password, and then with Google, Google still replaces it?
我做了更多探索并找到了答案 here。
正在粘贴相关代码段。
If there is an existing account with the same email address but created with non-trusted credentials (e.g. 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.
处理此问题的解决方案,即防止 Google 将现有提供商替换为 Google,是验证用户的电子邮件。
因此,在用户使用电子邮件和密码创建帐户或使用 Facebook(或任何其他提供商)登录后,向用户发送电子邮件验证 link。
用户验证 his/her 电子邮件后,随后的 Sign-in with Google
将不会替换现有提供商。