首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android: Google登录凭据标记列表总是空的。

Android: Google登录凭据标记列表总是空的。
EN

Stack Overflow用户
提问于 2015-12-17 11:59:14
回答 2查看 1.6K关注 0票数 1

我正在实现谷歌智能锁登录,以便在没有输入的情况下自动登录用户,但是我遇到的问题是,即使在“成功”连接之后,凭证对象令牌列表中返回的令牌列表(getIdTokens)仍然是空的。在什么时候,凭据对象实际上填充了一个令牌列表?

我使用这个例子来构建代码:

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

代码语言:javascript
复制
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();
        }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-31 03:41:50

凭据对象上的getIdTokens()应返回包含OpenID连接ID令牌的列表,如果凭据已通过Auth.CredentialsApi.request()Auth.CredentialsApi.getHintPickerIntent()方法检索,且凭据对应于在运行Play服务8+的设备上登录的Auth.CredentialsApi.request()帐户

请注意,在构造请求时应包括.setAccountTypes(IdentityProviders.GOOGLE)

代码语言:javascript
复制
    CredentialRequest request = new CredentialRequest.Builder()
            .setAccountTypes(IdentityProviders.GOOGLE)
            .setSupportsPasswordLogin(true)
            .build();

或者当收到提示时,如果没有保存的凭据可用:

代码语言:javascript
复制
    HintRequest hintRequest = new HintRequest.Builder()
            .setAccountTypes(IdentityProviders.GOOGLE)
            .setEmailAddressIdentifierSupported(true)
            .build();

如果凭据是用Credential.Builder构造的(如问题中代码的一部分所示),或者凭据与设备上的Google帐户的电子邮件地址不匹配,则不存在ID令牌。

所以有一些事情要检查:

  • 在运行最新版本Play Services的设备上进行测试(8.4)
  • 确保检索到的凭据与在设备上登录的Google帐户匹配,并且该帐户处于良好状态(同步、接收电子邮件、不需要重新输入密码等)。
  • 验证检索到的凭据以前是否保存在应用程序或相关网站中(通过Chrome密码管理器),或者来自用.setAccountType(IdentityProviders.GOOGLE)构建的.setAccountType(IdentityProviders.GOOGLE)

如果您在获取ID令牌时仍然有问题,请在您的环境详细信息中留下注释。

票数 1
EN

Stack Overflow用户

发布于 2017-12-26 12:13:38

我通过添加.setIdTokenRequested(true)在googlesamples/android凭据中找到了GitHub的解决方案。

代码语言:javascript
复制
CredentialRequest credentialRequest = new CredentialRequest.Builder()
                            .setPasswordLoginSupported(true)
                            .setAccountTypes(IdentityProviders.GOOGLE)
                            .setIdTokenRequested(true)
                            .build();
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34334069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档