基于 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 应用和您的应用所采取的流程步骤:
Google 应用会尝试打开您应用的通用链接。如果您的应用程序安装在用户的设备上并与通用链接相关联,则它可以打开您的应用程序。见支持通用链接了解详情。
您的应用程序检查该
client_id
和redirect_uri
在输入URL编码参数的预期谷歌的通用链接匹配。您的应用程序向您的 OAuth2 服务器请求授权码。在此流程结束时,您的应用会向 Google 应用返回授权代码或错误。为此,它会打开 Google 的通用链接,其中包含授权代码或错误的附加参数。
Google 应用程序处理传入的 Google 通用链接并继续执行流程的其余部分。如果提供授权码,则立即完成链接。令牌交换发生在服务器到服务器之间,与基于浏览器的 OAuth 链接流程中的方式相同。如果返回错误代码,链接流将继续使用替代选项。
修改您的 iOS 应用以支持 App Flip
要支持 App Flip,请对您的 iOS 应用程序进行以下代码更改:
- 处理
NSUserActivityTypeBrowsingWeb
在应用程序委托。 - 捕捉
redirect_uri
和state
从URL参数,以备后用。 - 检查
redirect_uri
匹配格式:https://oauth-redirect.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID https://oauth-redirect-sandbox.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID
验证客户端 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 } }
成功授权后,使用授权代码调用重定向 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) } }
如果发生错误,请将错误结果附加到重定向 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
):谷歌client_id
您的应用程序下注册的公司。 -
scope
(List of String
):请用空格隔开的范围列表。 -
state
(String
):由谷歌中使用的随机数,以验证该授权结果是响应于谷歌的呼出请求。 -
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
,以确保适当的后退时被trigerred。
修改您的授权端点以支持 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
收到请求时参数相匹配的预期值。如果客户端验证失败,返回错误invalid_request
到redirect_uri
。