适用于iOS的App Flip

基于 OAuth 的 App Flip 链接(App Flip)从 Google 应用打开您的 iOS 应用,以帮助 Google 应用用户更轻松地链接他们的帐户。您需要对 iOS 应用程序进行少量代码更改才能实现此功能。

在本文档中,您将了解如何修改您的 iOS 应用以支持 App Flip。

试试样品

该应用程序翻转示例应用程序演示连接iOS上的整合是公司的App翻转兼容的帐户。您可以使用此应用来验证如何响应来自 Google 移动应用的传入 App Flip 通用链接。

示例应用程序预配置与整合应用翻转测试工具为iOS ,你可以用它来验证您的iOS应用的使用App翻转整合之前配置帐户与谷歌联系起来。此应用模拟启用 App Flip 时由 Google 移动应用触发的通用链接。

这个怎么运作

以下是发生 App Flip 时 Google 应用和您的应用所采取的流程步骤:

  1. Google 应用会尝试打开您应用的通用链接。如果它安装在用户的设备上并与通用链接相关联,它就可以打开您的应用程序。见支持通用链接了解详情。

  2. 您的应用程序检查该client_idredirect_uri在输入URL编码参数的预期谷歌的通用链接匹配。

  3. 您的应用程序向您的 OAuth2 服务器请求授权码。在此流程结束时,您的应用会向 Google 应用返回授权代码或错误。为此,它会打开 Google 的通用链接,其中包含授权代码或错误的附加参数。

  4. Google 应用程序处理传入的 Google 通用链接并继续执行流程的其余部分。如果提供授权码,则立即完成链接。令牌交换发生在服务器到服务器之间,与基于浏览器的 OAuth 链接流程中的方式相同。如果返回错误代码,链接流将继续使用替代选项。

修改您的 iOS 应用以支持 App Flip

要支持 App Flip,请对您的 iOS 应用进行以下代码更改:

  1. 处理NSUserActivityTypeBrowsingWeb在应用程序委托。
  2. 捕捉redirect_uristate从URL参数,以备后用。
  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_idString ):谷歌client_id您的应用程序下注册的公司。
  • scopeList of String ):请用空格隔开的范围列表。
  • stateString ):由谷歌中使用的随机数,以验证该授权结果是响应于谷歌的呼出请求。
  • redirect_uriString ):谷歌的通用连接。用于打开 Google 应用并传递结果的“翻转”URI。

授权结果返回成功时使用的参数:

  • codeString ):授权码的所述的值(如果可用)。
  • stateString ):从输入的通用链路接收的精确值。

授权结果返回失败时使用的参数:

  • errorString ),具有以下值:

    • cancelled :可恢复的错误。 Google 应用将尝试使用授权 URL 关联帐户。一些示例是用户无法登录、设备离线或连接超时。
    • unrecoverable :不可恢复的错误。例如,用户尝试与禁用的帐户关联。Google 应用程序将中止帐户关联。
    • invalid_request :请求参数无效或丢失。这是一个可恢复的错误。 Google 应用将尝试使用授权 URL 关联帐户。
    • access_denied :用户拒绝同意请求。这是一个不可恢复的错误; Google 应用中止链接。
  • error_descriptionString ,可选):一个用户友好的错误消息。

修改您的授权端点以支持 App Flip

将您的平台配置为使用 Google 的 App Flip 重定向 URL 接受请求:

  • 谷歌主页的应用程序
    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
    
  • 谷歌应用程序助理
    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_id和由指定的URL redirect_uri收到请求时参数相匹配的预期值。