1. 소개
App Attest와 함께 Firebase 앱 체크를 사용하여 백엔드 서비스를 보호하고 Firebase 서비스에 대한 요청이 인증된 앱에서 전송되었는지 확인할 수 있습니다.
일반적으로 할당량 한도에 도달하지 않도록 사용자를 App Attest 서비스에 점진적으로 온보딩하는 것이 좋습니다. 자세한 내용은 Apple의 '앱 증명 서비스 사용 준비' 문서를 참고하세요.
'단계별 버전 업데이트 출시'에 설명된 대로 Apple의 App Store Connect 기능을 사용하여 점진적으로 앱 업데이트를 출시할 수 있어야 합니다. 앱 체크 출시가 더 원활하게 진행될 수 있습니다 이는 간단하고 직관적인 솔루션입니다. 하지만 앱 버전 업데이트를 단계적으로 출시해도 새 앱 버전을 게시하지 않고는 출시를 관리하거나 업데이트된 기존 앱의 동작을 변경할 수 없습니다.
App Attest로 앱 체크 출시를 더 효과적으로 제어하는 한 가지 방법은 Firebase 원격 구성을 사용하여 App Attest로 앱 체크를 사용하여 한 번에 일부 앱 사용자에 대해 앱 체크를 사용 설정하는 것입니다. 이렇게 하면 증명 서버에서 제한을 방지하는 데 도움이 될 수 있습니다. Google 애널리틱스를 사용하여 출시가 사용자에게 미치는 영향을 관찰할 수 있습니다.
학습 내용
이 다단계 Codelab에서는 Firebase 원격 구성을 사용하여 앱에 App Check를 출시하는 방법을 알아봅니다.
이 Codelab에서는 Apple 플랫폼용 Firebase 앱 체크 Codelab에 설명된 대로 DatabaseExample 빠른 시작 앱을 기반으로 Firebase 앱 체크와 통합된 Firebase 프로젝트를 사용합니다. DatabaseExample 빠른 시작 앱을 통해 사용자는 Firebase 실시간 데이터베이스의 기능을 사용하여 로그인하고 게시물을 추가할 수 있습니다.
이 Codelab의 단계를 조정하여 자체 앱을 테스트할 수도 있습니다.
기본 요건
필요한 사항
- Xcode 12.5 이상
- 앱 증명 테스트의 경우:
- 새 앱 식별자를 만들 수 있는 Apple 개발자 계정
- App Attest 기능이 사용 설정된 명시적 앱 ID가 있는 애플리케이션 이 과정에서 도움이 필요하면 앱 ID 등록 및 앱 기능 사용 설정 도움말을 참고하세요.
- App Attest를 지원하는 iOS/iPadOS 기기
- 다음 사항이 있는 Firebase 프로젝트:
- 구성된 iOS 앱 (자세히 알아보기)
- Google 애널리틱스, 원격 구성, 앱 체크가 사용 설정됨
- 원격 구성을 만들고 관리하며 Google 애널리틱스를 볼 수 있는 권한이 포함된 앱의 연결된 Firebase 프로젝트에 대한 액세스 권한
2. 맞춤 증명 제공업체 만들기
이 단계에서는 앱 증명이 사용 설정된 경우에만 토큰을 제공하는 맞춤 제공자 클래스를 만듭니다. 원격 구성은 구성된 Firebase 앱 인스턴스를 활용하며, 이 단계에서 구현하는 커스텀 제공업체는 구성을 완료하기 위한 자리표시자 역할을 합니다.
다음 단계를 완료하려면 Xcode에서 앱의 프레임워크, 라이브러리 및 삽입된 콘텐츠 섹션에 Firebase
, FirebaseRemoteConfig
, FirebaseAnalytics
를 추가해야 합니다. 이 작업을 수행하는 방법의 예는 Apple 플랫폼용 Firebase 앱 체크 Codelab을 참고하세요.
AppCheckProvider
프로토콜을 준수하는NSObject
의 서브클래스인 'MyAppCheckProvider' 파일을 만듭니다.- 나중에 작성할 빈
getToken()
메서드를 포함합니다.
빈 getToken()
메서드가 있는 맞춤 제공업체 클래스의 예는 다음 코드를 참고하세요.
// MyAppCheckProvider.swift
import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig
class MyAppCheckProvider: NSObject, AppCheckProvider {
func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}
AppAttestProvider
를 인스턴스화하려면 해당하는 FirebaseApp
의 인스턴스를 전달해야 합니다. 저장된 속성을 만들고 이니셜라이저 매개변수로 허용합니다.
// MyAppCheckProvider.swift
import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig
class MyAppCheckProvider: NSObject, AppCheckProvider {
// Firebase app instance served by the provider.
let firebaseApp: FirebaseApp
// The App Check provider factory should pass the FirebaseApp instance.
init(app: FirebaseApp) {
self.firebaseApp = app
super.init()
}
func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}
App Attest 제공업체에 토큰 요청 전달
이제 getToken()
메서드에서 토큰 요청을 App Attest 제공자로 전달할 준비가 되었습니다.
참고: FirebaseAppCheck 프레임워크 참조에서 getToken()
메서드에 대해 자세히 알아보세요.
getToken()
메서드에 다음 코드를 추가합니다.
// MyAppCheckProvider.swift
import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig
class MyAppCheckProvider: NSObject, AppCheckProvider {
// Firebase app instance served by the provider.
let firebaseApp: FirebaseApp
// The App Check provider factory should pass the FirebaseApp instance.
init(app: FirebaseApp) {
self.firebaseApp = app
super.init()
}
private lazy var appAttestProvider = AppAttestProvider(app: firebaseApp)
func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
// Fetch App Attest flag from Remote Config
let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
remoteConfig.fetchAndActivate { remoteConfigStatus, error in
// Get App Attest flag value
let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue
guard appAttestEnabled else {
// Skip attestation if App Attest is disabled. Another attestation
// method like DeviceCheck may be used instead of just skipping.
handler(nil, MyProviderError.appAttestIsDisabled)
return
}
// Try to obtain an App Attest provider instance and fail if cannot
guard let appAttestProvider = self.appAttestProvider else {
handler(nil, MyProviderError.appAttestIsUnavailable)
return
}
// If App Attest is enabled for the app instance, then forward the
// Firebase App Check token request to the App Attest provider
appAttestProvider.getToken(completion: handler)
}
}
}
enum MyProviderError: Error {
case appAttestIsDisabled
case appAttestIsUnavailable
case unexpected(code: Int)
}
이전 코드는 원격 구성 AppAttestEnabled
불리언 매개변수를 확인합니다(이 원격 구성 매개변수는 Codelab의 뒷부분에서 생성됨). 값이 false이면 코드가 실패하여 앱 체크가 현재 기기에 출시되지 않았음을 나타냅니다. 값이 true이면 코드는 앱 증명 제공업체를 가져오려고 시도하고 가져오지 못하면 실패합니다. 이러한 오류 검사가 통과되면 코드는 토큰 요청을 앱 증명 제공업체로 전달합니다.
애널리틱스 이벤트 추가
애널리틱스 이벤트를 추가하면 앱 체크 출시가 얼마나 성공적인지 더 잘 파악할 수 있습니다. 애널리틱스는 더 많은 잠재고객을 대상으로 App Attest를 사용 설정해야 하는지 결정하는 데 도움이 됩니다.
두 가지 애널리틱스 이벤트(성공 시 AppAttestSuccess, 실패 시 AppAttestFailure)를 로깅합니다. 이 두 가지 애널리틱스 이벤트를 사용하면 앱 체크 출시의 성공 여부를 추적하고 더 큰 규모의 출시를 진행할지 결정하는 데 도움이 됩니다.
func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
// Fetch Remote Config.
let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
remoteConfig.fetchAndActivate { remoteConfigStatus, error in
// Get App Attest flag value from Remote Config.
let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue
guard appAttestEnabled else {
// Skip attestation if App Attest is disabled. Another attestation
// method like DeviceCheck may be used instead of just skipping.
handler(nil, MyProviderError.appAttestIsDisabled)
return
}
// Try to obtain an App Attest provider instance and fail otherwise.
guard let appAttestProvider = self.appAttestProvider else {
handler(nil, MyProviderError.appAttestIsUnavailable)
return
}
// If App Attest is enabled for the app instance, then forward the
// Firebase App Check token request to the App Attest provider.
appAttestProvider.getToken { token, error in
// Log an Analytics event to track attestation success rate.
let appAttestEvent: String
if (token != nil && error == nil) {
appAttestEvent = "AppAttestSuccess"
} else {
appAttestEvent = "AppAttestFailure"
}
Analytics.logEvent(appAttestEvent, parameters: nil)
// Pass the result to the handler
handler(token, error)
}
}
}
3. 제공자 팩토리 클래스 업데이트
토큰 요청을 App Attest 제공자로 전달하는 로직을 구현하고 애널리틱스 이벤트를 몇 개 추가한 후에는 Apple 플랫폼용 앱 체크 Codelab에서 만든 MyAppCheckProviderFactory.class
를 업데이트해야 합니다. 이 클래스는 시뮬레이터의 경우 앱 체크 디버그 제공자를 타겟팅하며, 그 외의 경우에는 커스텀 제공자를 타겟팅합니다.
Apple 플랫폼용 Firebase 앱 체크 Codelab에서 만든 MyAppCheckProviderFactory
클래스에서 다음 코드를 수정합니다.
// MyAppCheckProviderFactory.swift
import Firebase
class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
#if targetEnvironment(simulator)
// App Attest is not available on simulators.
// Use a debug provider.
let provider = AppCheckDebugProvider(app: app)
// Print only locally generated token to avoid a valid token leak on CI.
print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "" )")
return provider
#else
if #available(iOS 14.0, *) {
// Use your custom App Attest provider on real devices.
return MyAppCheckProvider(app: app)
} else {
return DeviceCheckProvider(app: app)
}
#endif
}
}
FirebaseApp
를 구성하기 전에 AppCheckProviderFactory
를 설정했는지 확인합니다.
// DatabaseExampleApp.swift
import SwiftUI
import Firebase
import FirebaseAppCheck
@main
struct DatabaseExampleApp: App {
init() {
AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory())
FirebaseApp.configure()
}
// ...
}
4. Firebase Console에서 원격 구성 매개변수 추가
이제 Firebase Console에 원격 구성 매개변수 AppAttestEnabled를 추가합니다 . getToken
메서드에 이 매개변수가 필요합니다.
Firebase Console에서 원격 구성 매개변수를 만드는 방법은 다음과 같습니다.
- 프로젝트의 원격 구성을 열고 매개변수 추가를 클릭합니다. 원격 구성을 처음 사용하는 경우 구성 만들기를 클릭합니다.
- 매개변수 이름(키) 필드에
AppAttestEnabled
를 입력합니다. - 데이터 유형 드롭다운에서 불리언을 선택합니다.
- 기본값 드롭다운에서 false를 선택합니다.
'저장'을 클릭하기 전에 사용자의 10%에 대한 조건부 값을 만듭니다.
- 새로 추가를 클릭합니다. 조건부 값 > 새 조건 만들기
- 이름 필드에 조건 이름을 입력합니다.
- 적용 조건...에서 임의 백분위수의 사용자, <=를 선택한 후 % 필드에 10을 입력합니다.
- 조건 만들기를 클릭합니다.
앱 인증이 사용자의 10%에게 출시되도록 조건부 값을 true로 설정합니다.
- 방금 만든 조건의 값을 true로 설정합니다.
- 저장을 클릭합니다.
완료되면 원격 구성 변경사항을 게시합니다.
기기에서 출시 테스트
앱 코드를 수정하지 않고 기기에서 다양한 원격 구성 플래그 값을 테스트하려면 A/B 테스팅으로 Firebase 원격 구성 실험 만들기 튜토리얼에 따라 AppAttestEnabled 매개변수에서 실험을 구성합니다. '테스트 기기에서 실험 검증' 튜토리얼 섹션에서는 테스트 기기에 다른 값을 할당하는 방법을 설명합니다.
마지막 단계는 Google 애널리틱스를 사용하여 앱 증명 출시의 성공 여부를 모니터링하는 것입니다.
5. AppCheck 출시 성공 검토
애널리틱스 이벤트 대시보드에서 출시 성공을 측정할 수 있습니다. AppAttestSuccess 및 AppAttestFailure 이벤트를 확인합니다. 대시보드에 이벤트가 표시되는 데 최대 24시간이 걸릴 수 있습니다. 또는 디버깅을 사용 설정하고 DebugView를 사용하여 디버그 이벤트를 더 빠르게 확인할 수 있습니다.
원하는 경우 Crashlytics 대시보드에서 비정상 종료 발생률의 증가를 모니터링할 수 있습니다. 앱에 Crashlytics를 추가하는 방법에 대한 자세한 내용은 Firebase Crashlytics 시작하기를 참조하세요.
대부분 AppAttestSuccess 이벤트와 AppAttestFailure 이벤트가 거의 표시되지 않았다면 원격 구성 매개변수 AppAttestEnabled에서 조건을 수정하여 App Attest를 사용 설정한 사용자의 비율을 높일 수 있다는 좋은 신호입니다.
선택사항: Google 애널리틱스 잠재고객 활용
AppAttestEnabled 애널리틱스 이벤트를 더 활용하려면 애널리틱스 잠재고객을 만들어 AppAttestEnabled가 true로 설정된 사용자를 추적할 수 있습니다.
App Attest는 iOS 14.0과 함께 출시되었습니다. 일부 사용자는 이 버전을 사용하지 않을 수 있으므로 App Attest를 사용할 수 없습니다. 다른 애널리틱스 이벤트를 기록하여 이러한 사용자를 추적한 다음 DeviceCheck와 같은 다른 증명 방법으로 해당 잠재고객을 타겟팅할 수 있습니다.
선택사항: Crashlytics를 사용하여 비정상 종료 모니터링
출시 중에 앱의 안정성을 더 잘 이해하려면 Firebase Crashlytics를 사용하여 비정상 종료 및 심각하지 않은 문제를 모니터링하세요.
6. 수고하셨습니다.
원격 구성으로 앱 체크가 출시되었습니다. 🎉