Google 계정으로 로그인을 사용하여 인증 관리자 통합

선택할 수 있는 다양한 ID가 표시된 인증 관리자를 사용하는 하단 시트
그림 1. 인증 관리자 API와 통합한 후의 Google 계정으로 로그인 하단 시트 대화상자

이 문서에서는 Google ID 도우미 라이브러리를 사용하여 Google ID 서비스(GIS)에서 인증 관리자 API로 Google 계정으로 로그인 하단 시트 대화상자를 이전하는 방법을 설명합니다.

인증 관리자 API를 사용하는 앱은 최종 사용자에게 일관된 Android 사용자 인터페이스를 표시하도록 구성됩니다. 이러한 사용자 인터페이스를 사용하면 사용자가 패스키 지원 계정을 포함하여 저장된 로그인 옵션 목록에서 선택할 수 있습니다. 이 API는 다른 사용자 인증 정보 유형과 제공업체를 통합할 때 권장됩니다. Android 14부터 사용자는 Credential Manager API와 함께 서드 파티 비밀번호 관리자를 활용할 수도 있습니다.

종속 항목 선언

모듈의 build.gradle 파일에서 최신 버전을 사용하여 종속 항목을 선언합니다.

dependencies {
  // ... other dependencies

  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

안내에 따라 Google API 콘솔 프로젝트를 설정합니다. 종속 항목 포함에 대한 안내를 위에 언급된 안내로 대체합니다.

Google 로그인 요청 인스턴스화

구현을 시작하려면 Google 로그인 요청을 인스턴스화하세요. GetGoogleIdOption을 사용하여 사용자의 Google ID 토큰을 가져옵니다.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

먼저 setFilterByAuthorizedAccounts 매개변수를 true로 설정하여 API를 호출해야 합니다. 사용할 수 있는 사용자 인증 정보가 없는 경우 API를 다시 호출하고 setFilterByAuthorizedAccountsfalse로 설정합니다.

가능한 경우 자동으로 사용자가 로그인되도록 하려면 GetGoogleIdOption 요청에서 setAutoSelectEnabled로 이 기능을 사용 설정하세요. 다음 기준이 충족되면 자동 로그인이 가능합니다.

  • 앱에 저장된 사용자의 사용자 인증 정보가 정확히 한 개입니다. 즉, 저장된 비밀번호 또는 저장된 Google 계정이 한 개입니다.
  • 사용자가 Google 계정 설정에서 자동 로그인을 사용 중지하지 않았습니다.

로그인 보안을 강화하고 재생 공격을 방지하려면 setNonce를 사용하여 각 요청에 nonce를 포함하세요. nonce 생성 자세히 알아보기

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>);
  .build();

Google 계정으로 로그인

Google 계정으로 로그인 흐름을 설정하는 단계는 다음과 같습니다.

  1. GetCredentialRequest를 인스턴스화하고 위에서 만든 googleIdOption을 추가하여 사용자 인증 정보를 가져옵니다.
  2. 이 요청을 getCredential()(Kotlin) 또는 getCredentialAsync()(Java) 호출에 전달하여 사용자의 사용 가능한 사용자 인증 정보를 가져옵니다.
  3. API가 성공하면 GoogleIdTokenCredential 데이터의 결과가 포함된 CustomCredential을 추출합니다.
  4. CustomCredential의 유형은 GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL의 값과 같아야 합니다. GoogleIdTokenCredential.createFrom 메서드를 사용하여 객체를 GoogleIdTokenCredential로 변환합니다.
  5. 변환에 성공하면 GoogleIdTokenCredential의 ID를 추출하고 검증하여 서버에서 사용자 인증 정보를 인증합니다.
  6. GoogleIdTokenParsingException과 함께 변환에 실패하면 Google 계정으로 로그인 라이브러리 버전을 업데이트해야 할 수도 있습니다.
  7. 인식할 수 없는 맞춤 사용자 인증 정보 유형을 포착합니다.

Kotlin

val request: GetCredentialRequest = Builder()
  .addGetCredentialOption(googleIdOption)
  .build()

coroutineScope.launch {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    handleFailure(e)
  }
}

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse on your server to
      // validate and authenticate
      responseJson = credential.authenticationResponseJson
    }

    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      } else {
        // Catch any unrecognized custom credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

Java

GetCredentialRequest request = new GetCredentialRequest.Builder()
  .addGetCredentialOption(googleIdOption)
  .build();

// Launch sign in flow and do getCredential Request to retrieve the credentials
credentialManager.getCredentialAsync(
  requireActivity(),
  request,
  cancellationSignal,
  <executor>,
  new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
    @Override
    public void onResult(GetCredentialResponse result) {
      handleSignIn(result);
    }

    @Override
    public void onError(GetCredentialException e) {
      handleFailure(e);
    }
  }
);

public void handleSignIn(GetCredentialResponse result) {
  // Handle the successfully returned credential.
  Credential credential = result.getCredential();

  if (credential instanceof PublicKeyCredential) {
    String responseJson = ((PublicKeyCredential) credential).getAuthenticationResponseJson();
    // Share responseJson i.e. a GetCredentialResponse on your server to validate and authenticate
  } else if (credential instanceof PasswordCredential) {
    String username = ((PasswordCredential) credential).getId();
    String password = ((PasswordCredential) credential).getPassword();
    // Use id and password to send to your server to validate and authenticate
  } else if (credential instanceof CustomCredential) {
    if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
      try {
        // Use googleIdTokenCredential and extract id to validate and
        // authenticate on your server
        GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(((CustomCredential) credential).getData());
      } catch (GoogleIdTokenParsingException e) {
        Log.e(TAG, "Received an invalid Google ID token response", e);
      }
    } else {
      // Catch any unrecognized custom credential type here.
      Log.e(TAG, "Unexpected type of credential");
    }
  } else {
    // Catch any unrecognized credential type here.
    Log.e(TAG, "Unexpected type of credential");
  }
}

Google 계정으로 로그인 버튼

Google 계정으로 로그인 버튼은 최신 Google ID 도우미 라이브러리가 포함된 인증 관리자에서 지원됩니다. Google 계정으로 로그인 버튼 흐름을 트리거하려면 GetGoogleIdOption 대신 GetSignInWithGoogleOption을 사용하고 반환된 GoogleIdTokenCredential을 이전과 같은 방식으로 처리합니다.

Google 계정으로 가입하기

GetGoogleIdOption 요청을 인스턴스화하고 GetCredentialsRequest에 전달하는 동안 setFilterByAuthorizedAccountstrue로 설정한 후에도 결과가 반환되지 않으면 로그인할 수 있는 승인된 계정이 없다는 의미입니다. 이 시점에서 setFilterByAuthorizedAccounts(false)를 설정하고 Google 계정으로 가입을 호출해야 합니다.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

Google 가입 요청을 인스턴스화한 후 Google 계정으로 로그인 섹션에서 언급한 것과 유사한 방식으로 인증 흐름을 시작합니다.

로그아웃 처리

사용자가 앱에서 로그아웃하면 API clearCredentialState() 메서드를 호출하여 현재 사용자 인증 정보 상태를 지우고 로그인 내부 상태를 재설정합니다.