iOS용 앱 플립

OAuth 기반 앱 플립 연결 (앱 플립)은 Google 앱에서 iOS 앱을 엽니다. Google 앱 사용자가 계정을 더 쉽게 연결할 수 있습니다. 다음과 같이 코드를 약간 변경해야 이 기능을 구현할 수 있습니다.

이 문서에서는 앱 플립을 지원하도록 iOS 앱을 수정하는 방법을 알아봅니다.

샘플 사용해 보기

앱 플립 샘플 앱 앱 플립과 호환되는 iOS에서의 계정 연결 통합을 보여줍니다. 이 앱을 사용하여 수신되는 App Flip 범용에 응답하는 방법을 확인할 수 있습니다. Google 모바일 앱에서 링크를 걸 수 있습니다.

샘플 앱은 App Flip Test Tool과 통합되도록 사전 구성되어 있으며 iOS 이전에 iOS 앱과 앱 플립의 통합을 확인하는 데 사용할 수 있는 Google과의 계정 연결을 구성해야 합니다 이 앱은 범용 링크를 시뮬레이션합니다. 앱 플립이 사용 설정된 경우 Google 모바일 앱에 의해 트리거됩니다.

작동 방식

다음은 Google 앱 및 앱에서 진행할 때 거치는 흐름 단계입니다. 앱 뒤집기 발생:

  1. Google 앱에서 앱의 범용 링크를 열려고 합니다. 다음을 할 수 있습니다. 앱이 사용자 기기에 설치되어 있고 Google Play와 연결되어 있으면 사용할 수 있습니다. 자세한 내용은 범용 링크 지원을 참고하세요.

  2. 앱은 client_idredirect_uri 매개변수가 예상되는 Google 범용 링크와 일치하는지 확인합니다.

  3. 앱에서 OAuth2 서버로부터 승인 코드를 요청합니다. 끝부분 앱이 승인 코드나 오류를 반환하여 Google 앱 이를 위해 Google 범용 링크에 매개변수입니다.

  4. Google 앱은 수신되는 Google 범용 링크를 처리하고 확인할 수 있습니다. 승인 코드가 제공되면 연결은 다음과 같습니다. 즉시 완료됩니다. 토큰 교환은 서버 간에 발생하며 사용하는 방식으로 작동합니다. 오류 코드가 반환되면 대체 옵션으로 연결 흐름이 계속됩니다.

앱 플립을 지원하도록 iOS 앱 수정

앱 플립을 지원하려면 iOS 앱에서 다음과 같이 코드를 변경합니다.

  1. 앱 대리자에서 NSUserActivityTypeBrowsingWeb를 처리합니다.
  2. 나중에 사용할 수 있도록 URL에서 redirect_uristate 매개변수를 캡처합니다.
  3. redirect_uri가 다음 형식과 일치하는지 확인합니다.
    https://oauth-redirect.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID
    https://oauth-redirect-sandbox.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID
  4. 클라이언트 ID가 예상 값과 일치하는지 확인합니다. 다음을 사용하세요. 코드 샘플입니다

    func application(_ application: UIApplication,
                     continue userActivity: NSUserActivity,
                     restorationHandler: @escaping ([Any]?) -> Void) -> Bool
    {
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
            let incomingURL = userActivity.webpageURL,
            let components = URLComponents(url: incomingURL, resolvingAgainstBaseURL: false),
            let params = components.queryItems else {
                return false
        }
    
        if let clientId = params.filter({$0.name == "client_id"}).first?.value,
            let state = params.filter({$0.name == "state"}).first?.value,
            let redirectUri = params.filter({$0.name == "redirect_uri"}).first?.value {
    
            // Save the redirect_uri and state for later...
    
            // Verify the client id
            return (clientId == GOOGLE_CLIENT_ID)
        } else {
            // Missing required parameters
            return false
        }
    }
    
  5. 인증에 성공하면 승인과 함께 리디렉션 URI를 호출합니다. 있습니다. 다음 코드 샘플을 사용하세요.

    func returnAuthCode(code: String, state: String, redirectUri: String) {
        var redirectURL = URL(string: redirectUri)
        var components = URLComponents(url: redirectURL, resolvingAgainstBaseURL: false)
    
        // Return the authorization code and original state
        let paramAuthCode = URLQueryItem(name: "code", value: code)
        let paramState = URLQueryItem(name: "state", value: state)
        components?.queryItems = [paramAuthCode, paramState]
        if let resultURL = components?.url {
            UIApplication.shared.open(
                resultURL,
                options: [UIApplicationOpenURLOptionUniversalLinksOnly : true],
                completionHandler: nil)
        }
    }
    
  6. 오류가 발생한 경우에는 오류 결과를 리디렉션 URI에 첨부하세요. 다음 코드 샘플을 사용하세요.

    func returnError(redirectUri: String) {
        var redirectURL = URL(string: redirectUri)
        var components = URLComponents(url: redirectURL, resolvingAgainstBaseURL: false)
    
        // Return the authorization code and original state
        let paramError = URLQueryItem(name: "error", value: "invalid_request")
        let paramDescription = URLQueryItem(name: "error_description", value: "Invalid Request")
        components?.queryItems = [paramError, paramDescription]
        if let resultURL = components?.url {
            UIApplication.shared.open(
                resultURL,
                options: [UIApplicationOpenURLOptionUniversalLinksOnly : true],
                completionHandler: nil)
        }
    }
    

Google 앱에서 열면 앱의 범용 링크에는 다음이 포함됩니다. 쿼리 매개변수를 제공합니다.

  • client_id (String): 앱에 등록된 Google client_id입니다.
  • scope (List of String): 요청된 공백으로 구분된 범위 목록입니다.
  • state (String): Google에서 승인을 확인하는 데 사용하는 nonce입니다. Google의 발신 요청에 대한 응답으로 제공됩니다.
  • redirect_uri (String): Google 범용 링크입니다. 뒤집기 열려는 URI 결과를 전달할 수 있습니다

승인 결과가 성공적으로 반환될 때 사용되는 매개변수:

  • code(String): 승인 코드의 값입니다(사용 가능한 경우).
  • state (String): 수신 범용 링크에서 받은 정확한 값입니다.

승인 결과가 실패했을 때 사용되는 매개변수:

  • 다음 값을 포함하는 error (String)

    • cancelled: 복구 가능한 오류입니다. Google 앱에서 계정을 다시 시도합니다. 승인 URL을 사용하여 연결합니다. 몇 가지 예는 사용자가 기기가 오프라인 상태이거나 연결 시간이 초과되어 로그인할 때 문제가 발생할 수 있습니다.
    • unrecoverable: 복구할 수 없는 오류입니다. 예를 들어 사용자가 사용 중지된 계정과 연결을 시도합니다.Google 앱에서 계정 연결을 중단합니다.
    • invalid_request: 요청 매개변수가 잘못되었거나 누락되었습니다. 이는 복구 가능한 오류입니다. Google 앱에서 승인 URL을 사용하여 계정 연결을 시도합니다.
    • access_denied: 사용자가 동의 요청을 거부합니다. 복구할 수 없는 오류입니다. Google 앱이 연결을 중단한 경우
  • error_description (String, 선택사항): 사용자 친화적인 오류 메시지입니다.

모든 오류 유형에서 응답 데이터를 지정된 REDIRECT_URI: 적절한 대체가 트리거되도록 합니다.

앱 플립을 지원하도록 승인 엔드포인트 수정

Google의 앱 플립 리디렉션 URL을 사용하여 요청을 수락하도록 플랫폼을 구성합니다.

  • Google Home 앱
    https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast.dev
    https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast.enterprise
    https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast.dev
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast.enterprise
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast
    
  • Google 어시스턴트 앱
    https://oauth-redirect.googleusercontent.com/a/com.google.OPA.dev
    https://oauth-redirect.googleusercontent.com/a/com.google.OPA.enterprise
    https://oauth-redirect.googleusercontent.com/a/com.google.OPA
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA.dev
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA.enterprise
    https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA
    

client_idredirect_uri 매개변수로 지정된 URL을 확인합니다. 요청이 수신될 때 예상 값과 일치함을 확인합니다. 클라이언트 확인이 실패하면 invalid_request 오류를 redirect_uri에 반환합니다.