CamHart CamHart - 3 months ago 19
Android Question

Android App using AWS Cognito, Google+ OAuth, and AccountManager

I've been trying to setup Google+ OAuth and AWS Cognito on my Android app. Right now I have Google+ OAuth working I believe, because I'm able to get the account off the call below:

GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);


From that result object I can get certain data outlined below:

if (result.isSuccess()) {

GoogleSignInAccount account = result.getSignInAccount();
String authCode = account.getServerAuthCode(); //null
String displayName =account.getDisplayName(); //correct value
String email = account.getEmail(); //correct value
String id = account.getId(); //correct value
String idToken = account.getIdToken(); //null
...


However, when I follow AWS's documentation, I get errors and deprecated methods. Here's the code block I'm trying to mimic from AWS's documentation:

Documentation: http://docs.aws.amazon.com/cognito/latest/developerguide/google.html#set-up-google-1.android#Android

//From Documentation ^
GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
String token = GoogleAuthUtil.getToken(getApplicationContext(), accounts[0].name,
"audience:server:client_id:YOUR_GOOGLE_CLIENT_ID");
Map<String, String> logins = new HashMap<String, String>();
logins.put("accounts.google.com", token);
credentialsProvider.setLogins(logins);


Here is where I'm running into problems:

AccountManager am = AccountManager.get(context);
Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);


After this call accounts is an empty array--do I need to do something to ensure the OAuth process puts the information in the AccountManager?

*** One other thing I wasn't sure about, the AWS documentation (from the link above) states as Step #5 for setting up google that I should do the following steps which I can't seem to get right: "Under Credentials > Add Credentials, create a Service Account. The console will alert you that a new public/private key has been created."

Google has changed their UI and there are now 3 options, creating a custom service account, and using one of two default accounts (app engine / computation engine). Which should I do?

Answer

Okay I figured it out. Key changes from the Amazon aws and google documentation.

  1. GoogleSignInOptions needs to ask for an id token. You do this like so:

    googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(Scopes.PLUS_LOGIN)) //<- this is optional
            //requestIdToken takes the google cloud console's project's WEB (not Android)
            .requestIdToken("in this string put your google web client id")
            .requestEmail()
            .build();
    
  2. Then when you get the results back you'll have the id token

    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
    GoogleSignInAccount account = result.getSignInAccount();
    String idToken = account.getIdToken();
    
  3. Now you can use that id token to gain aws credentials through cognito.

    Map logins = new HashMap(); logins.put("accounts.google.com", token); credentialsProvider.setLogins(logins); //credentialsProvider is a CognitoCachingCredentialsProvider object

Now you should be all set.

Comments