从适用于Android的Google登录迁移到Firebase身份验证

Che*_*eng 10 android firebase-authentication google-signin

目前,我们计划使用Google Sign-In for Android作为我们的服务器身份验证方法.

这是我们打算做的.

客户端(适用于Android的Google登录)

GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// This idToken will sent to backend server.
String idToken = account.getIdToken();
Run Code Online (Sandbox Code Playgroud)

服务器端(适用于Android的Google登录)

// Based on received idToken from client, backend server will call https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=... 
// to identify who is this user.

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}
Run Code Online (Sandbox Code Playgroud)

将来,我们可能希望迁移以提供更多登录选项.这是我未来的迁移计划,可以从Google登录Android迁移到Firebase身份验证.

客户端(Firebase身份验证)

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
    .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
        public void onComplete(@NonNull Task<GetTokenResult> task) {
            if (task.isSuccessful()) {
                // This idToken will sent to backend server.
                String idToken = task.getResult().getToken();

            } else {
                // Handle error -> task.getException();
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

服务器端(适用于Android的Google登录)

# idToken comes from the client app (shown above)
decoded_token = auth.verify_id_token(idToken)
uid = decoded_token['uid']
Run Code Online (Sandbox Code Playgroud)

我的问题是

  1. 对于Android版Google登录,我们计划将其存储"sub": "110169484474386276334"为代表用户的唯一标识符.这是一个正确的字段吗?每个用户是否独一无二?到目前为止,我的测试是,在客户端,我们可能会idToken因同一个用户(在不同的日期)而有所不同.与idToken同一用户不同,在服务器端仍然会产生相同的效果sub.

  2. 有一天,我们可能会迁移到Firebase身份验证以支持更多登录方法.它是否仍然向后兼容Google Sign-In for Android.是否Firebase Authentication能够返回相同"sub"的是什么以前返回Google Sign-In for Android?正如您在代码示例中看到的那样,Firebase Authentication正在返回uid.

我如何比较新Firebase Authenticationuid,以及之前存储Google Sign-Insub

Mar*_*ler 1

Q1:基本上在这里得到了回答:

Google 帐户的电子邮件地址可能会更改,因此请勿使用它来识别用户的身份。相反,请使用帐户的 ID,您可以通过在客户端上获取该 ID GoogleSignInAccount.getId(),并在后端通过subID 令牌的声明获取该 ID。

问题 2:Google 作为 Firebase 的身份验证提供商仍然使用相同的 Google 登录流程(一开始),同时它还根据 Firebase 项目对用户进行身份验证。

有一个例子说明了这一点:

private void signIn() {
    Intent signInIntent = mGoogleSignInClient.getSignInIntent();
    startActivityForResult(signInIntent, REQUESTCODE_SIGN_IN);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
    if (requestCode == REQUESTCODE_SIGN_IN) {

        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        try {

            // Google Sign In was successful
            GoogleSignInAccount account = task.getResult(ApiException.class);
            String idToken = account.getIdToken();
            // Send token to your backend via HTTPS

            // authenticate with Firebase
            firebaseAuthWithGoogle(account);

        } catch (ApiException e) {
            Log.w(TAG, "Google sign in failed", e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

哪里GoogleSignInAccount account仍然是相同的反应。

编辑:甚至可以通过类似方式验证 ID 令牌:FirebaseAuth

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();

mUser.getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
    public void onComplete(@NonNull Task<GetTokenResult> task) {
        if (task.isSuccessful()) {

            String idToken = task.getResult().getToken();
            // Send token to your backend via HTTPS

        } else {
            // Handle error -> task.getException();
        }
    }
});
Run Code Online (Sandbox Code Playgroud)