One Tap 로그인이 요구 사항을 충족하는 경우 대신 사용하는 것이 좋습니다. One Tap에는 업데이트된 사용자 경험과 기타 개선 사항이 있습니다.

사용자의 저장된 사용자 인증 정보 가져오기

Credentials API를 사용하여 사용자의 저장된 사용자 인증 정보를 요청하고 가져와 사용자에게 자동으로 앱에 로그인합니다.

시작하기 전에

Android 스튜디오 프로젝트 구성

CredentialsClient 객체 만들기

저장된 사용자 인증 정보를 요청하려면 Credentials API에 액세스할 수 있도록 CredentialsClient의 인스턴스를 만들어야 합니다.

CredentialsClient mCredentialsClient;

// ...

mCredentialsApiClient = Credentials.getClient(this);

CredentialRequest 객체 생성

CredentialRequest 객체는 사용자 인증 정보를 요청할 로그인 시스템을 지정합니다. 비밀번호 기반 로그인에는 setPasswordLoginSupported 메서드를, Google 로그인과 같은 제휴 로그인 서비스는 setAccountTypes() 메서드를 사용하여 CredentialRequest를 빌드합니다.

mCredentialRequest = new CredentialRequest.Builder()
    .setPasswordLoginSupported(true)
    .setAccountTypes(IdentityProviders.GOOGLE, IdentityProviders.TWITTER)
    .build();

IdentityProviders에 정의된 상수를 사용하여 일반적으로 사용되는 로그인 제공업체를 지정합니다. 다른 로그인 제공업체의 경우 제공업체를 고유하게 식별하는 문자열을 사용합니다. 사용자 인증 정보를 검색하는 데 사용하는 것과 동일한 제공업체 식별자를 사용하여 사용자 인증 정보를 저장해야 합니다.

저장된 사용자 인증 정보 요청

CredentialsClientCredentialRequest 객체를 만든 후에는 요청 객체를 CredentialsClient.request() 메서드에 전달하여 앱에 저장된 사용자 인증 정보를 요청합니다.

  mCredentialsClient.request(mCredentialRequest).addOnCompleteListener(
      new OnCompleteListener<CredentialRequestResponse>() {
          @Override
          public void onComplete(@NonNull Task<CredentialRequestResponse> task) {

              if (task.isSuccessful()) {
                  // See "Handle successful credential requests"
                  onCredentialRetrieved(task.getResult().getCredential());
                  return;
              }

              // See "Handle unsuccessful and incomplete credential requests"
              // ...
          }
      });

addOnCompleteListener() 메서드를 사용하여 성공 및 실패한 요청을 처리하는 콜백을 정의합니다.

성공적인 사용자 인증 정보 요청 처리

로그인 완료를 나타내는 토스트 메시지사용자 인증 정보 요청에 성공하면 Credential 객체를 사용하여 앱에 대한 사용자 로그인을 완료합니다. getAccountType() 메서드를 사용하여 검색된 사용자 인증 정보 유형을 결정한 다음 적합한 로그인 프로세스를 완료합니다. 예를 들어 Google 로그인의 경우 사용자 ID를 포함하는 GoogleSignInClient 객체를 만든 다음 이 객체를 사용하여 로그인 과정을 시작합니다. 비밀번호 기반 로그인의 경우 사용자 인증 정보 객체의 사용자 ID와 비밀번호를 사용하여 앱의 로그인 프로세스를 완료합니다.

private void onCredentialRetrieved(Credential credential) {
    String accountType = credential.getAccountType();
    if (accountType == null) {
        // Sign the user in with information from the Credential.
        signInWithPassword(credential.getId(), credential.getPassword());
    } else if (accountType.equals(IdentityProviders.GOOGLE)) {
        // The user has previously signed in with Google Sign-In. Silently
        // sign in the user with the same ID.
        // See https://developers.google.com/identity/sign-in/android/
        GoogleSignInOptions gso =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestEmail()
                        .build();

        GoogleSignInClient signInClient = GoogleSignIn.getClient(this, gso);
        Task<GoogleSignInAccount> task = signInClient.silentSignIn();
        // ...
    }
}

저장된 여러 사용자 인증 정보 처리

Smart Lock 계정 선택기

사용자 인증 정보를 선택하기 위해 사용자 입력이 필요한 경우 request() 작업이 ResolvableApiException와 함께 실패합니다. getStatusCode()RESOLUTION_REQUIRED를 반환하는지 확인하고 사용자에게 계정을 선택하라는 메시지를 표시하려면 예외의 startResolutionForResult() 메서드를 호출합니다. 그런 다음 Credential.EXTRA_KEYgetParcelableExtra() 메서드에 전달하여 활동의 onActivityResult() 메서드에서 사용자가 선택한 사용자 인증 정보를 검색합니다.

mCredentialsClient.request(request).addOnCompleteListener(
        new OnCompleteListener() {
            @Override
            public void onComplete(@NonNull Task task) {
                if (task.isSuccessful()) {
                    // ...
                    return;
                }

                Exception e = task.getException();
                if (e instanceof ResolvableApiException) {
                    // This is most likely the case where the user has multiple saved
                    // credentials and needs to pick one. This requires showing UI to
                    // resolve the read request.
                    ResolvableApiException rae = (ResolvableApiException) e;
                    resolveResult(rae, RC_READ);
                } else if (e instanceof ApiException) {
                    // The user must create an account or sign in manually.
                    Log.e(TAG, "Unsuccessful credential request.", e);

                    ApiException ae = (ApiException) e;
                    int code = ae.getStatusCode();
                    // ...
                }
            }
        });
private void resolveResult(ResolvableApiException rae, int requestCode) {
    try {
        rae.startResolutionForResult(MainActivity.this, requestCode);
        mIsResolving = true;
    } catch (IntentSender.SendIntentException e) {
        Log.e(TAG, "Failed to send resolution.", e);
        hideProgress();
    }
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // ...

    if (requestCode == RC_READ) {
        if (resultCode == RESULT_OK) {
            Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
            onCredentialRetrieved(credential);
        } else {
            Log.e(TAG, "Credential Read: NOT OK");
            Toast.makeText(this, "Credential Read Failed", Toast.LENGTH_SHORT).show();
        }
    }

    // ...

}

저장된 사용자 인증 정보를 찾을 수 없는 경우 사용자는 계정을 만들거나 수동으로 로그인해야 합니다. getStatusCode()에서 SIGN_IN_REQUIRED를 반환하면 사용자에게 이메일 주소와 이름 등 최근에 사용한 로그인 정보를 선택하라는 메시지를 표시하여 가입 및 로그인 프로세스를 가속화하고 양식의 일부 필드를 해당 정보로 자동으로 채울 수 있습니다. 자세한 내용은 사용자에게 로그인 힌트 제공을 참고하세요.

로그인에 성공하면 사용자가 사용자 인증 정보를 저장하도록 허용하여 모든 기기에서 향후 인증을 자동화합니다.