Developer Console

Integrate A3L Authentication SDK

Use this guide to integrate your app with the A3L Authentication SDK.

Setup A3L Authentication sign-in

To integrate A3L Authentication into your Android app, you must configure A3L Authentication and add a button to start the sign-in flow.

Initialize A3L Authentication

In your sign-in activity's onCreate() method, initialize A3L Authentication, providing the Android client ID you got from the Google API Console, as shown in the following code.

try{
    A3LAuth.init(<PREFIX>);
} catch(APIException e) {
    e.printStackTrace();
}

The default solution for devices with Google Play services is Google Sign-In. Devices without Google Play services default to AppAuth. If you prefer to provide a similar experience to users and use AppAuth as the solution on all devices, initialize your app as shown in the following code.

try{
    A3LAuth.init(<PREFIX>, true);
} catch(APIException e) {
    e.printStackTrace();
}

Configure A3LSignIn and A3LSignInClient objects

Next, configure the A3LSignIn and A3LSignInClient objects by following these steps.

  1. In the onCreate() method, configure A3L Authentication to request the user data that your app requires through an A3LSignInOptions object.

    For example, to configure A3L Authentication to request a user's ID and basic profile information, build an A3LSignInOptions object using the DEFAULT_SIGN_IN parameter. If you want to also request a user's email address, include the requestEmail() option when you create the A3LSignInOptions object, as shown here.

     // Configure sign in to request the user's ID, email address, and basic
     // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
     A3LSignInOptions a3LSignInOptions = new A3LSignInOptions
                                     .Builder(A3LSignInOptions.DEFAULT_SIGN_IN)
                                     .requestEmail()
                                     .build();
    
  2. In the onCreate() method, create an A3LSignInClient object using the options you specified in the A3LSignInOptions object that you created in the previous step, as shown in the following code.

     // Build a A3LSignInClient with the options specified by 
     // A3LSignInOptions object created above.
     mA3LSignInClient = A3LSignIn.getClient(this, a3LSignInOptions);
    

Check for a signed-in user

Before displaying the sign-in flow, check if the user is already signed in to the app by using the getLastSignedInAccount() method. In your activity's onStart() method, check if the user is already signed in, as shown in this example.

// Check for existing Sign In account, if the user is already signed in
// the A3LSignInAccount will be non-null.
A3LSignInAccount account = A3LSignIn.getLastSignedInAccount(this);
updateUI(account);

If a non-null A3LSignInAccount object is returned, it means the user is already signed in to the app and you don't have to prompt them again. You can progress the user to your app's post sign-in experience.

If null is received, that means the user is not signed in to the app. Provide the sign-in button for the user to sign in to the app.

private void updateUI(A3LSignInAccount account) {
    if (account!=null) {
        // provide the signed-in experience to the user
    } else {
        // provide sign-in button and other info for user to sign in to the app
    }
}

Add a sign-in button to your app

You can create a custom sign-in button for your app, but if you want to use the default sign-in button provided by Google, follow the steps listed below.

  1. Add the sign-in button in your app layout.

     <com.google.android.gms.common.SignInButton 
     android:id="@+id/sign_in_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" />
    
  2. In the Android activity, add an OnClickListener to the button. For example, you can add the following code in the onCreate() method.

     findViewById(R.id.sign_in_button).setOnClickListener(this);
    

    When a user clicks this button, your app start the sign-in flow, described in the next section.

Handle sign-in

Sign in the user with these steps.

  1. In the activity's onClick() method, handle the case when a user presses the sign-in button.

     @Override
     public void onClick(View v) {
         switch (v.getId()) {
             case R.id.sign_in_button:
                 signIn();
                 break;
             // ...
         }
     }
    

    In the signIn() method, create a sign-in intent using the getSignInIntent() method. Start the intent with the startActivityForResult() method as shown here.

     private void signIn() {
         Intent signInIntent = mA3LSignInClient.getSignInIntent();
         startActivityForResult(signInIntent, RC_SIGN_IN);
     }
    

    Starting the intent has different behavior depending on the device the app is run on. For an Android device that supports Google Play services, the user is prompted, within the app, to select an account to sign in with. For devices without Google Play services, the app opens a Custom Tab and redirects the user to Google's authentication webpage.

    In both cases, the user is prompted to select a Google account to sign in with, or to enter the email address that they want to sign in with.

  2. In the onActivityResult() method, use the A3LSignIn.getSignedInAccountFromIntent() method to get a task that will return a A3LSignInAccount object when successful, as shown here.

     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
    
         // Result returned from launching the Intent from A3LSignInClient.getSignInIntent(...);
         if (requestCode == RC_SIGN_IN) {
             Task<A3LSignInAccount> task = A3LSignIn.getSignedInAccountFromIntent(data);
             handleSignInResult(task);
         }
     }
    

    The implementation of the handleSignInResult() method follows. The resulting A3LSignInAccount object contains information about the signed-in user, such as their name.

     private void handleSignInResult(Task<A3LSignInAccount> completedTask) {
         completedTask.addOnCompleteListener(new OnCompleteListener<A3LSignInAccount>() {
             @Override
             public void onComplete(@NonNull Task<A3LSignInAccount> task) {
                 try {
                     A3LSignInAccount account = task.getResult();
                     updateUI(account);
                 } catch (Exception e) {
                     Log.e(TAG, "signInResult:failed code=" + e.getMessage());
                     updateUI(null);
                 }
             }
         });
     }
    

    To access user data from the A3LSignInAccount object, use the following methods:

    • getEmail() to get the user's email address
    • getId() to get the user's Google ID for client-side use
    • getIdToken() to get an ID token for the user

    To pass the currently signed-in user to a back-end server, send the ID token to your back-end server and validate the token on the server.

Access user profile information

How you configured the A3LSignInOptions object in Configure A3LSignIn and A3LSignInClient objects determines which information you can access from the signed-in user. If you configured A3LSignInOptions with the DEFAULT_SIGN_IN parameter or the requestProfile() method, you can access the user's basic profile information after they sign in. If you configured A3LSignInOptions with the requestEmail() method, you can also access the user's email address.

To request profile information for the currently signed-in user, use the A3LSignIn.getLastSignedInAccount() method, as shown in the following example.

A3LSignInAccount acct = A3LSignIn.getLastSignedInAccount(getActivity());
if (acct != null) {
  String personName = acct.getDisplayName();
  String personGivenName = acct.getGivenName();
  String personFamilyName = acct.getFamilyName();
  String personEmail = acct.getEmail();
  String personId = acct.getId();
  Uri personPhoto = acct.getPhotoUrl();
}

To see all potential fields that you can access from an A3LSignInAccount object, see the A3L Authentication API Reference.

Sign out users

Provide a way for users to sign out of your app by adding a sign-out button. After you create a sign-out button, attach an OnClickListener to the button and configure the onClick() method to call the signOut() method, as shown in the following code.

@Override
public void onClick(View v) {
    switch (v.getId()) {
        // ...
        case R.id.button_sign_out:
            signOut();
            break;
        // ...
    }
}

private void signOut() {
    mA3LSignInClient.signOut()
            .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    // ...
                }
            });
}

When your app runs this code, the user's Google account is signed out of your app. The user can choose to sign in again with their Google account without any prompts for permissions, such as requesting access to specified scopes.

Disconnect accounts

Provide users with the ability to disconnect their Google account from your app. If a user chooses to disconnect their account from your app, you must delete the information that your app obtained from Google's APIs. When you revoke access, it removes the permissions that the user has given to your app to access their data through the scopes.

To disconnect a user's account, call the revokeAccess() method, as shown in the following example.

private void revokeAccess() {
    mA3LSignInClient.revokeAccess()
            .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    // ...
                }
            });
}

In the OnCompleteListener, your app can respond to the event and run any additional required code.

Revoke access differences

Revoking access to the app is provided in A3L Authentication, but it differs from Google's revoke access⁠ functionality. When revoking access using Google Sign-In, the app is removed from user's Google account. This is not the case in A3L Authentication. In A3L Authentication, the revoke access functionality revokes the access of user from the app and remove the permissions to access the data given to the app, but it doesn't delete the entries in the user's account. To remove the app from the entries, follow the Google developer documentation on Revocation methods.

Authenticate with a back-end server

If you're using A3L Authentication and your app communicates with a back-end server, you might need to identify the currently signed-in user on the server. To securely identify the currently signed-in user, use HTTPS to send the user's ID token to your server. On the server, verify the integrity of the ID token. Use the user data from the token to establish a session with a known user or to create a new account record for a new user.

Fetch the ID token

First, you must fetch the user's ID token when they sign in. Configure A3L Authentication with the requestIdToken() method and pass your server's web client ID to this method, as shown here.

// Request only the user's ID token, which can be used to identify the
// user securely to your backend. This will contain the user's basic
// profile (name, profile picture URL, etc) so you should not need to
// make an additional call to personalize your app.
A3LSignInOptions a3LSignInOptions = new A3LSignInOptions.Builder(A3LSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(getString(R.string.server_client_id))
        .requestEmail()
        .build();

When the user signs in, get the A3LSignInAccount object from the activity result of the sign-in intent:

Task<A3LSignInAccount> task = A3LSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);

After the user signs in, get the ID token from the A3LSignInAccount object, as shown here.

private void handleSignInResult(@NonNull Task<A3LSignInAccount> completedTask) {
    completedTask.addOnCompleteListener(new OnCompleteListener<A3LSignInAccount>() {
        @Override
        public void onComplete(@NonNull Task<A3LSignInAccount> task) {
            try {
                A3LSignInAccount account = task.getResult();
                String idToken = account.getIdToken();
                // handle ID Token
            } catch (Exception e) {
                Log.w(TAG, "signInResult:failed code=" + e.getMessage());
                updateUI(null);
            }
        }
    });
}

Send the ID token to your server

Use an HTTPS POST request to send the ID token to your server, as shown here.

HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://yourbackend.example.com/tokensignin");

try {
  List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
  nameValuePairs.add(new BasicNameValuePair("idToken", idToken));
  httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

  HttpResponse response = httpClient.execute(httpPost);
  int statusCode = response.getStatusLine().getStatusCode();
  final String responseBody = EntityUtils.toString(response.getEntity());
  Log.i(TAG, "Signed in as: " + responseBody);
} catch (ClientProtocolException e) {
  Log.e(TAG, "Error sending ID token to backend.", e);
} catch (IOException e) {
  Log.e(TAG, "Error sending ID token to backend.", e);
}

After you fetch the ID token, validate it by following the instructions in Google's developer documentation, Verify the integrity of the ID token.


Last updated: Dec 05, 2023