앱 체크를 사용하여 Android용 Navigation SDK 보호하기

Firebase 앱 체크는 정상적인 앱이 아닌 소스에서 발생하는 트래픽을 차단하여 앱에서 Google Maps Platform으로의 호출을 보호합니다. 이를 위해 Play Integrity와 같은 증명 제공업체에 앱 또는 기기의 신뢰성 평가를 요청합니다. 앱을 앱 체크와 통합하면 악의적이고 승인되지 않은 요청으로부터 앱을 보호할 수 있으며, 이를 통해 승인되지 않은 청구로부터 결제를 보호할 수 있습니다. 또한 앱 체크는 차량 앱 생태계의 실시간 중단 보고를 크게 개선하여 앱을 사용하는 모든 운전자에게 이점을 제공합니다. 자세한 내용은 중단 보고를 참고하세요.

앱 체크를 사용하는 이유

앱 체크는 Android용 Navigation SDK의 두 가지 영역, 즉 기본 탐색 기능과 중단 보고를 보호합니다.

앱 체크는 악의적이거나 승인되지 않은 소스에서 전송되는 기본 Android용 Navigation SDK 요청을 차단하는 데 도움이 됩니다. 이는 결제 사기 및 할당량 소진으로부터 프로젝트를 보호하여 직접적인 이점을 제공합니다.

중단 신고

앱에서 실시간 중단 보고 및 투표 기능을 지원하는 경우 앱 체크를 사용하는 것이 좋습니다. 앱 체크를 사용 설정하면 운전자에게 모든 실시간 피드백을 반영한 가장 정확한 경로가 제공됩니다.

보고에서 앱 체크가 중요한 이유:

  • 폐쇄에 대한 높은 신뢰 기준: 도로 폐쇄와 같이 경로에 영향을 미치는 이벤트는 모든 운전자의 경로 동작을 크게 바꿀 수 있습니다. 잠재적인 파손 행위, 스팸, 부정확한 신고로부터 지도를 보호하기 위해 Google의 도로 폐쇄 중단 관리 인프라는 강력한 기기 및 앱 무결성 신호에 의존합니다.
  • 앱 체크에서 신고를 검증하는 방법: Android용 Navigation SDK에서 전송된 사용자 신고 및 투표에는 앱 체크 토큰이 포함됩니다. 이 토큰은 Google 백엔드에서 의견의 적법성을 검증하는 데 사용되며, 이를 통해 신뢰 수준을 높이고 라이브 지도에 미치는 영향을 평가할 수 있습니다.
  • 앱 체크를 생략할 경우의 영향: 유효한 앱 체크 토큰 없이 제출된 신고는 신뢰도가 낮은 모델로 평가되며, 무음 신호로만 처리될 수 있습니다. 즉, 사용자가 계속 신고하고 투표할 수 있지만, 신고가 지도에 표시되거나 다른 운전자의 경로에 영향을 미칠 가능성이 낮으며 추가 검증이 필요합니다.

앱 체크가 나에게 적합한가요?

대부분의 경우 앱 체크를 사용하는 것이 좋지만 다음 시나리오에서는 앱 체크가 필요하지 않거나 지원되지 않습니다.

  • 비공개 또는 실험용 앱: 앱에 공개적으로 액세스할 수 없는 경우 앱 체크가 필요하지 않습니다.
  • 보안 침해된 기기: 권장 증명 제공업체는 루팅되거나 탈옥된 휴대전화와 같이 신뢰할 수 없는 기기에서 Android용 Navigation SDK가 실행되지 않도록 합니다. 이러한 기기를 지원하려면 커스텀 증명 제공업체를 배포하세요.
  • 비 GMS Android 기기: Android 기기는 Play Integrity를 위해 Google 모바일 서비스 (GMS)를 실행해야 합니다. GMS가 아닌 Android 기기를 지원하려면 커스텀 증명 제공업체를 배포합니다.

구현 단계 개요

대략적으로 다음 단계에 따라 앱을 앱 체크와 통합합니다.

  1. 앱에 Firebase를 추가합니다.
  2. 앱 체크 라이브러리를 추가하고 앱 체크를 초기화합니다.
  3. 토큰 제공업체를 추가합니다. 이 단계에서는 선택한 증명 제공자를 호출하여 기기 또는 앱의 무결성을 확인합니다.
  4. Navigation API 및 App Check API를 초기화합니다.
  5. 디버깅을 사용 설정합니다. 이는 개발 중이거나 지속적 통합 (CI) 환경에서 유용합니다.
  6. 시정 조치를 사용 설정하기 전에 앱 요청을 모니터링하세요. 이렇게 하면 사용자를 방해하지 않고 앱 체크를 원활하게 시행할 수 있습니다.

앱 체크 통합 계획 시 고려사항

  • 증명 제공업체 할당량: Google에서 권장하는 증명 제공업체인 Play Integrity는 표준 API 사용 등급에 일일 호출 한도가 있습니다. 호출 한도에 관한 자세한 내용은 Google Play Integrity 개발자 문서의 설정 페이지를 참고하세요.
  • 시작 지연 시간: 대부분의 경우 앱 체크 토큰이 기기에 캐시되므로 일반적인 사용 중에는 지연 시간이 발생하지 않습니다. 시스템은 원활한 성능을 유지하기 위해 만료 전에 백그라운드에서 앱 체크 토큰을 자동으로 새로고침합니다. 하지만 유효한 앱 체크 토큰이 없으면 앱 사용자가 시작 시 약간의 지연 시간을 경험하게 됩니다. 예를 들어 이 지연 시간은 캐시된 토큰이 만료되었거나 누락된 콜드 스타트 중에 발생합니다.
  • 토큰 TTL: TTL (수명)은 앱 체크 토큰이 새로고침되기 전에 유효한 기간을 결정합니다. Firebase Console에서 이 기간을 30분에서 7일 사이로 구성할 수 있습니다. 안전한 기준으로는 1시간이 권장되지만 SDK는 TTL 기간의 약 절반에서 백그라운드 새로고침을 자동으로 시도합니다. 단계별 Console 안내는 Firebase 앱 체크 문서를 참고하세요.

앱 체크와 앱 통합

기본 요건 및 요구사항

  • Android용 Navigation SDK 버전 7.9 이상이 설치된 앱
  • 앱의 SHA-256 인증서 지문입니다.
  • 앱의 패키지 이름입니다.
  • Google Cloud 콘솔에서 앱의 소유자여야 합니다.
  • Google Cloud 콘솔의 앱 프로젝트 ID입니다.

1단계: 앱에 Firebase 추가

Firebase 개발자 문서의 안내에 따라 앱에 Firebase를 추가합니다. 프로젝트의 앱 수준 디렉터리에 google-services.json 파일을 추가합니다.

2단계: 앱 체크 라이브러리 추가 및 앱 체크 초기화

앱의 build.gradle 파일에 앱 체크 종속 항목을 추가합니다.

Groovy (build.gradle)

dependencies {
    // Import the Firebase BoM
    implementation platform('com.google.firebase:firebase-bom:34.17.0')
    // Add the dependency for the App Check library with Play Integrity
    implementation 'com.google.firebase:firebase-appcheck-playintegrity'
}

Application 클래스 또는 기본 활동에서 앱 체크를 초기화합니다.

자바

import com.google.firebase.FirebaseApp;
import com.google.firebase.appcheck.FirebaseAppCheck;
import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory;

// Initialize Firebase App
FirebaseApp.initializeApp(/* context= */ this);

// Initialize App Check
FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
firebaseAppCheck.installAppCheckProviderFactory(
    PlayIntegrityAppCheckProviderFactory.getInstance());

Kotlin

import com.google.firebase.Firebase
import com.google.firebase.appcheck.appCheck
import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory
import com.google.firebase.initialize

// Initialize Firebase App
Firebase.initialize(context = this)

// Initialize App Check
Firebase.appCheck.installAppCheckProviderFactory(
    PlayIntegrityAppCheckProviderFactory.getInstance(),
)

3단계: 토큰 제공업체 추가하기

MapsAppCheckTokenProvider 인터페이스의 구현을 만듭니다. 이 제공자는 Firebase 앱 체크에서 앱 체크 토큰을 비동기식으로 가져와 MapsAppCheckTokenCallback를 사용하여 Android용 Navigation SDK 네트워크 스택에 전달합니다.

자바

import com.google.android.gms.maps.MapsAppCheckTokenCallback;
import com.google.android.gms.maps.MapsAppCheckTokenProvider;
import com.google.firebase.appcheck.FirebaseAppCheck;

public class NavigationTokenProvider implements MapsAppCheckTokenProvider {
  @Override
  public void fetchToken(MapsAppCheckTokenCallback callback) {
    FirebaseAppCheck.getInstance()
        .getAppCheckToken(false) // forcingRefresh = false
        .addOnSuccessListener(
            tokenResult -> {
              String token = tokenResult.getToken();
              callback.onSuccess(token);
            })
        .addOnFailureListener(
            e -> {
              callback.onFailure();
            });
  }
}

Kotlin

import com.google.android.gms.maps.MapsAppCheckTokenCallback
import com.google.android.gms.maps.MapsAppCheckTokenProvider
import com.google.firebase.appcheck.FirebaseAppCheck

class NavigationTokenProvider : MapsAppCheckTokenProvider {
    override fun fetchToken(callback: MapsAppCheckTokenCallback) {
        FirebaseAppCheck.getInstance()
            .getAppCheckToken(false)
            .addOnSuccessListener { tokenResult ->
                callback.onSuccess(tokenResult.token)
            }
            .addOnFailureListener {
                callback.onFailure()
            }
    }
}

4단계: Navigation API 및 App Check API 초기화

Android용 Navigation SDK를 초기화하고 MapsApiSettings.setAppCheckTokenProvider()를 사용하여 통합 토큰 제공자 인스턴스를 등록합니다.

자바

import com.google.android.gms.maps.MapsApiSettings;

// Register your App Check token provider before initializing Navigation SDK for Android
MapsApiSettings.setAppCheckTokenProvider(context, new NavigationTokenProvider());

Kotlin

import com.google.android.gms.maps.MapsApiSettings

// Register your App Check token provider before initializing Navigation SDK for Android
MapsApiSettings.setAppCheckTokenProvider(context, NavigationTokenProvider())

5단계: 디버깅 사용 설정 (선택사항)

Android용 Navigation SDK에 앱 체크가 적용되면 Android용 Navigation SDK에 종속된 앱의 기능이 시뮬레이터 또는 지속적 통합 (CI) 환경에서 실행되지 않습니다. 이러한 환경은 유효한 기기로 인정되지 않기 때문입니다. 개발 및 테스트 중에 이러한 환경에서 앱을 실행하려면 프로덕션 증명 제공자 대신 앱 체크 디버그 제공자를 사용하는 앱의 디버그 빌드를 만들어야 합니다.

  1. 앱의 build.gradle 파일에 디버그 제공업체 종속 항목을 추가합니다.

    Groovy (build.gradle)

    dependencies {
        implementation 'com.google.firebase:firebase-appcheck-debug'
    }
  2. 디버그 빌드에서 디버그 제공자 팩토리를 사용하도록 앱 체크를 구성합니다.

    자바

    import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory;
    import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory;
    
    if (BuildConfig.DEBUG) {
        firebaseAppCheck.installAppCheckProviderFactory(
            DebugAppCheckProviderFactory.getInstance()
        );
    } else {
        firebaseAppCheck.installAppCheckProviderFactory(
            PlayIntegrityAppCheckProviderFactory.getInstance()
        );
    }

    Kotlin

    import com.google.firebase.Firebase
    import com.google.firebase.appcheck.appCheck
    import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory
    import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory
    
    if (BuildConfig.DEBUG) {
        Firebase.appCheck.installAppCheckProviderFactory(
            DebugAppCheckProviderFactory.getInstance(),
        )
    } else {
        Firebase.appCheck.installAppCheckProviderFactory(
            PlayIntegrityAppCheckProviderFactory.getInstance(),
        )
    }
  3. 에뮬레이터 또는 디버그 기기에서 앱을 실행합니다. 앱 체크가 로컬 디버그 토큰을 logcat 출력에 출력합니다.
  4. 이 디버그 토큰을 복사하여 Firebase Console에 등록합니다. 자세한 내용은 Firebase 앱 체크 디버그 제공자 문서를 참고하세요.

6단계: 앱 요청 모니터링 및 시정 조치 결정

적용을 사용 설정하기 전에 앱 요청을 모니터링하여 정당한 사용자에게 불편을 야기하지 않는지 확인하세요.

  1. Firebase Console의 앱 체크 측정항목 화면에서 확인된 트래픽과 확인되지 않은 트래픽의 비율을 확인합니다.
  2. 대부분의 트래픽이 확인되고 적법한 사용자가 앱 체크 구현이 포함된 앱 버전으로 업데이트한 것을 확인한 후 시행을 사용 설정합니다.
  3. 적용이 사용 설정되면 앱 체크에서 유효한 앱 체크 토큰이 없는 모든 트래픽을 거부합니다.