0

Я внедряю знак интеллектуальной блокировки Google для автоматического входа пользователя в систему без ввода, однако я столкнулся с проблемой возврата списка токенов (getIdTokens) в списке токенов объекта доверия всегда пуст даже после «успешного» соединения. В какой момент фактический объект учетных данных заполняется списком токенов?Android: Google Войти - учетный список токенов всегда пуст

Я использую этот пример, чтобы построить код:

https://github.com/googlesamples/android-credentials/blob/master/credentials-signin/app/src/main/java/com/google/example/credentialssignin/MainActivity.java#L101

private void googleSilentSignIn() { 
     // Try silent sign-in with Google Sign In API 
     OptionalPendingResult<GoogleSignInResult> opr = 
       Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); 
     if (opr.isDone()) { 
      GoogleSignInResult gsr = opr.get(); 
      handleGoogleSignIn(gsr); 
     } else { 
      opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { 
       @Override 
       public void onResult(GoogleSignInResult googleSignInResult) { 
        handleGoogleSignIn(googleSignInResult); 
       } 
      }); 
     } 
    } 


private void handleGoogleSignIn(GoogleSignInResult gsr) { 
     Timber.i("handleGoogleSignIn:" + (gsr == null ? "null" : gsr.getStatus())); 

     boolean isSignedIn = (gsr != null) && gsr.isSuccess(); 
     if (isSignedIn) { 
      // Display signed-in UI 
      GoogleSignInAccount gsa = gsr.getSignInAccount(); 
      String status = String.format("Signed in as %s (%s)", gsa.getDisplayName(), 
        gsa.getEmail()); 

      Timber.d("handleGoogleSignIn %s", status); 

      // Save Google Sign In to SmartLock 
      Credential credential = new Credential.Builder(gsa.getEmail()) 
        .setAccountType(IdentityProviders.GOOGLE) 
        .setName(gsa.getDisplayName()) 
        .setProfilePictureUri(gsa.getPhotoUrl()) 
        .build(); 

      saveCredentialIfConnected(credential); 

      Timber.d("handleGoogleSignIn: credential tokens was %s", credential.getIdTokens().toString()); 
} 
} 

    private void requestCredentials(final boolean shouldResolve, boolean onlyPasswords) { 
    Timber.d("requestCredentials"); 

    CredentialRequest.Builder crBuilder = new CredentialRequest.Builder() 
      .setPasswordLoginSupported(true); 

    if (!onlyPasswords) { 
     crBuilder.setAccountTypes(IdentityProviders.GOOGLE); 
    } 

    Auth.CredentialsApi.request(mGoogleApiClient, crBuilder.build()).setResultCallback(
      new ResultCallback<CredentialRequestResult>() { 
       @Override 
       public void onResult(CredentialRequestResult credentialRequestResult) { 
        Status status = credentialRequestResult.getStatus(); 

        if (status.isSuccess()) { 
         // Auto sign-in success 

         Timber.d("requestCredentials:onsuccess with token size %d", credentialRequestResult.getCredential().getIdTokens().size()); 

         handleCredential(credentialRequestResult.getCredential()); 
        } else if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED 
          && shouldResolve) { 
         // Getting credential needs to show some UI, start resolution 
         resolveResult(status, RC_CREDENTIALS_READ); 
        } 
       } 
      }); 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    if (!mIsResolving) { 
     requestCredentials(true /* shouldResolve */, false /* onlyPasswords */); 
    } 
} 


private void handleCredential(Credential credential) { 

     Timber.i("handleCredential with %s %s %s %s %s", credential.getId(), credential.getAccountType(), credential.getGeneratedPassword(), credential.getName(), credential.getPassword()); 

     mCredential = credential; 

     if (IdentityProviders.GOOGLE.equals(credential.getAccountType())) { 
      // Google account, rebuild GoogleApiClient to set account name and then try 
      buildGoogleApiClient(credential.getId()); 
      googleSilentSignIn(); 
     } 
} 

ответ

1

getIdTokens() на верительный объект должен возвращать список, содержащий маркер OpenID Connect ID, когда учетные данные были получены через Auth.CredentialsApi.request() или Auth.CredentialsApi.getHintPickerIntent(), а учетные данные соответствуют учетной записи Google, подписанной на устройстве, использующем Службы воспроизведения 8+

Обратите внимание, что .setAccountTypes(IdentityProviders.GOOGLE) должны быть включены при создании запроса:

CredentialRequest request = new CredentialRequest.Builder() 
      .setAccountTypes(IdentityProviders.GOOGLE) 
      .setSupportsPasswordLogin(true) 
      .build(); 

или при получении подсказку, если не сохранены учетные данные не доступны:

HintRequest hintRequest = new HintRequest.Builder() 
      .setAccountTypes(IdentityProviders.GOOGLE) 
      .setEmailAddressIdentifierSupported(true) 
      .build(); 

Там не будет ID маркера, если полномочие построен с Credential.Builder (как показано в части кода в вопросе), или если учетные данные не совпадают с адресом электронной почты учетной записи Google на устройстве.

Так что некоторые вещи, чтобы проверить:

  • тест на устройстве под управлением последней версии Play Services (8.4)

  • гарантировать, что извлеченный учетных данных соответствует аккаунт Google подписан в на устройстве и что учетная запись находится в хорошем состоянии (синхронизируется, получает электронную почту, не требуется вводить пароль и т. д.)

  • убедитесь, что ранее сохраненные учетные данные были сохранены в приложении или ассоциациях сайт Ted (через менеджер паролей Chrome), или вышел из HintRequest построен с .setAccountType(IdentityProviders.GOOGLE)

Если у вас есть проблемы с получением ID маркеров, оставьте комментарий с деталями вашей среды.

0

У меня также был пул списка idTokens. Наконец я нашел решение в googlesamples/андроид-учетные данные на GitHub, добавив .setIdTokenRequested (правда)

CredentialRequest credentialRequest = new CredentialRequest.Builder() 
          .setPasswordLoginSupported(true) 
          .setAccountTypes(IdentityProviders.GOOGLE) 
          .setIdTokenRequested(true) 
          .build();