javaandroidandroid-credential-manager

GoogleSignInClient.silentSignIn equivalent flow in Credential Manager API and Authorization API?


Previously, this is our flow of using GoogleSignInClient to interact with Google Drive service.

Deprecated legacy code

// GoogleSignInClient.silentSignIn() -> GoogleSignInAccount -> Drive object

GoogleSignInClient googleSignInClient = buildGoogleSignInClient();

Task<GoogleSignInAccount> task = googleSignInClient.silentSignIn();

GoogleSignInAccount googleSignInAccount = task.getResult()

Drive drive = getDriveService(googleSignInAccount)

public static GoogleSignInClient buildGoogleSignInClient() {
    GoogleSignInOptions signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(GOOGLE_DRIVE_CLIENT_ID)
            .requestEmail()
            .requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
            .build();
    return GoogleSignIn.getClient(WeNoteApplication.instance(), signInOptions);
}

private static Drive getDriveService(GoogleSignInAccount googleSignInAccount) {
    GoogleAccountCredential credential =
        GoogleAccountCredential.usingOAuth2(
            MyApplication.instance(), Collections.singleton(DriveScopes.DRIVE_APPDATA)
        );

    credential.setSelectedAccount(googleSignInAccount.getAccount());
    Drive googleDriveService =
            new Drive.Builder(
                    AndroidHttp.newCompatibleTransport(),
                    new GsonFactory(),
                    credential
            )
            .setApplicationName(APPLICATION_NAME)
            .build();

    return googleDriveService;
}

Now, we are trying to meet the deprecation deadline of GoogleSignInClient - https://android-developers.googleblog.com/2024/09/streamlining-android-authentication-credential-manager-replaces-legacy-apis.html

Based on https://stackoverflow.com/a/78605090/72437

It seems like I can skip using Credential Manager API (authentication), and jump directly into Authorization API (authorization)

https://developers.google.com/identity/authorization/android (authorization)

But, what is the replacement for the deprecated googleSignInClient.silentSignIn?

By having googleSignInClient.silentSignIn, it enables user to just sign in once, and can keep using Google Drive service without expiry for long period of time.

May I know, how can we achieve equivalent by using Authorization API?

Thanks.


Solution

  • You can do either of the following two approaches:

    1. Use the Credential Manager to sign the user up for your app/service. Then when you need to gain Drive access, you can call the Authorization APIs (asking for only the Drive scope). If user is signed in, then they won't see the account picker in the Authorization dialog and can directly see the consent page. If they give consent, then you get back an access token that you can use to call the Drive APIs. If you need offline access as well, when making the authorization request, you can ask for that too and as a result, you also get an auth code that can be exchanged for a refresh token to maintain your access over time. Note that if your user has already consented to drive access, then subsequent calls to the authorization API will return an access token without prompting the user. Same is for the CredentialManager: if user has already given consent to sharing the email+profile+openid with you the first time, then you can call the Credential Manager and set the appropriate parameters and your user will sign-in again automatically and you get an ID Token.
    2. You can just call the Authorization API and ask for email+profile+openid+drive scopes. LIke before, if user has already given consent, user will not be prompted again and you get the access token immediately.

    I presume you knew these two possibilities and there is something more that you want to accomplish. CredentialManager doesn't have "silentSignIn()" method but I don't think it needs one since it allows a no-prompt interaction for returning users and if there is no such user, it shows the bottomsheet to sign the user in.