How to detect if user sign-in or signed-out using Google One Tap in Android Native Library (Java/Kotlin) and get credential data (tokens) on return?

Viewed 1516

Quoting Google link https://developers.google.com/identity/one-tap/android/get-saved-credentials

If your Activity could be used by a signed-in user or a signed-out user, check the user's status before displaying the One Tap sign-in UI.

So, how do I know if user is signed-in or signed-out? The document talks about checking user's status but it is not clear if there is an API to check the status or the developer is expected to maintain the user's status in own code.

My use case is user uses one tap to login and then quits the app. The user then relaunches the app to get automatically logged-in without seeing any sign-in UI. It is also not clear as how can app read id token, access token etc. when user returns back to app.

3 Answers

Developers are expected to maintain the user's status in their own code.

If you detect that the user is already signed-in, you'll choose to not display One Tap.

One Tap performs user authentication and returns only a JWT ID token, OAuth2 access or refresh tokens are no longer returned or necessary.

If a user signs out of your app, you'll display One Tap and after the user signs into their Google Account the ID token will be returned.

You already linked to your answer, it was just deep in the documentation: Depending on the code you are using, will decide what code you need to check for user status. These links do provide Java and Kotlin examples to work from:

  1. Store Credentials - question 2
  2. Request Stored Credentials - question 2
  3. Check For Signed In User - question 1
  • how to detect if user is logged in - that's what the One Tap API does using OAtuh-Passes a token from Google to your App to say yes or no on valid credentials matching the token sent from Google API to your app. Your app then stores the token, wherever you point it to, and then -how to get access token of logged in user-you look where you pointed previously. Regradless, YOU have to create the user status code on the APP end, Google will not send you credentials to store anymore that's the whole Point of OAuth.

1) how to detect if a user is logged in?

  • You can get last signIn value using GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getApplicationContext());. If it is null then user is not signIn and if it is not null then user is SignIn.

     GoogleSignInAccount account = 
     GoogleSignIn.getLastSignedInAccount(getApplicationContext());
     if(account!=null){
        //Sign in
     } else{
        //not sign in
     }
    

Edit:

  • As per Google one Tap Sign-in and Sign-Up documentation, you need to check whether user is Sign-in or Sign-out using user credentials. If user is Sign-in then you will get non-null googleIdToken.

The user's response to the One Tap sign-in prompt will be reported to your app using your Activity's onActivityResult() method. If the user chose to sign in, the result will be a saved credential. If the user declined to sign in, either by closing the One Tap UI or tapping outside it, the result will return with the code RESULT_CANCELED. Your app needs to handle both possibilities.

Sign in with retrieved credentials If the user chose to share credentials with your app, you can retrieve them by passing the intent data from onActivityResult() to the One Tap client's getSignInCredentialFromIntent() method. The credential will have a non-null googleIdToken property if the user shared a Google Account credential with your app, or a non-null password property if the user shared a saved password.

Use the credential to authenticate with your app's backend.

If a username and password pair was retrieved, use them to sign in the same way you would if the user had manually supplied them. If Google Account credentials were retrieved, use the ID token to authenticate with your backend. If you've chosen to use a nonce to help avoid replay attacks check the response value on your backend server.

Note: you can save credentials(Token Id) into SharedPreferences to check Sign in status and then you can decide that when you need to show the One Tap UI.

Click to Check the documentation

2) you can get accessToken using GoogleAuthorizationCodeTokenRequest.

 // Load client secrets.
            AssetManager am = getAssets();
            InputStream in = am.open("credentials.json");
            if (in == null) {
                throw new FileNotFoundException("Resource not found: " + in);
            }
            GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
            final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
            GoogleTokenResponse tokenResponse =
                    new GoogleAuthorizationCodeTokenRequest(
                            HTTP_TRANSPORT,
                            JSON_FACTORY,
                            "https://oauth2.googleapis.com/token",
                            clientSecrets.getDetails().getClientId(),
                            clientSecrets.getDetails().getClientSecret(),
                            AuthCodePre.getString("Auth", ""),// account authcode
                            "http://localhost") // this redirect URL you also need to pass in your google console.
                            .setScopes(Arrays.asList(SCOPES))
                            .execute();

            String accessToken = tokenResponse.getAccessToken();
Related