原文链接:Implementing OAuth with ASWebAuthenticationSession | Kodeco
iOS 用 ASWebAuthenticationSession 实现 OAuth 登录
了解令牌
登录时,用户现在能够获得一个授权码。尽管如此,这还不是结尾。 该拜访码的持续有效期间很短,而且只能被运用一次。 意图是为了用它交流拜访令牌和改写令牌。
正如之前你看到的,拜访令牌在你每次发送恳求时都会带上以授权恳求。改写令牌的存活期间更长。 你能够在当时的拜访令牌过期时用改写令牌来获取一个新的拜访令牌。
处理令牌
运用手中的授权码,现在能够用它来交流令牌了。 你也会在 App 中增加逻辑来正确地处理它们。
翻开NetworkRequest.swift 。
在start(responseType:completionHandler:)
中的紧接着以下代码:
guard
error == nil,
let data = data
else {
DispatchQueue.main.async {
let error = error ?? NetworkRequest.RequestError.otherError
completionHandler(.failure(error))
}
return
}
找到代码行:
if let object = try? JSONDecoder().decode(responseType, from: data) {
将该行替换为以下代码:
// 1
if T.self == String.self,
let responseString = String(data: data, encoding: .utf8) {
// 2
let components = responseString.components(separatedBy: "&")
var dictionary: [String: String] = [:]
// 3
for component in components {
let itemComponents = component.components(separatedBy: "=")
if let key = itemComponents.first,
let value = itemComponents.last {
dictionary[key] = value
}
}
// 4
DispatchQueue.main.async {
// 5
NetworkRequest.accessToken = dictionary["access_token"]
NetworkRequest.refreshToken = dictionary["refresh_token"]
completionHandler(.success((response, "Success" as! T)))
}
return
} else if let object = try? JSONDecoder().decode(T.self, from: data) {
令牌交流呼应会回来一个字符串,可是其它 GitHub API 呼应是JSON格局的。 这里便是如何处理这种情况:
- 增加该句子,首先会看到有一个字符串呼应作为内容。
- 该呼应字符串,里面包括令牌,是用 & 分离隔的多个键值对,这也是将字符串分割成键值对数组的原因。
- 循环 components 的各个元素得到呼应的 Swift 字典。
- 由于
URLSession
的默认线程模型,现在所有的处理都是在后台运行。因此,要调用DispatchQueue
来唤醒主线程中的下一步处理。需求这么做的原因是完结处理器只会在主线程完结后更新 UI 。 - 该代码块在
NetworkRequest
的两个辅佐属性中存储了拜访令牌和更新令牌。然后会调用完结处理器,提示处理已经成功。
NetworkRequest 如何处理令牌。
要想看一下 NetworkRequest
对令牌作了什么处理,要的到 NetworkRequest+User.swift 。
它们是 String
类型的属性,在这背面它们向 UserDefaults
读写令牌,这样能够在 App 发动后保持。
这些令牌属于敏感数据,所以在你的 App 中,所以在 App 中,你想要确保它们安全地存储在 钥匙链中。 这是一个很有意思的课题,你能够在 如何维护 iOS 用户数据:SwiftUI 中的钥匙链服务和生物辨认技能 了解到更多内容。
编译运行。登录。模态控制器会再次在屏幕上闪一下,之后你就能够看到你的代码仓库的列表了:
太棒了!
创建时间短 SESSION (会话)
最后一个课题触及的是时间短会话 ,它是私有的认证会话。 时间短会话不会向磁盘缓存会话相关的数据,而是缓存在 RAM 中。 会话过期后,时间短会话 会清空会话数据。 这会很方便赋予用户增加的隐私信息和安全信息。
翻开SignInViewModel.swift。 在 signInTapped
中以下代码的下面:
authenticationSession.presentationContextProvider = self
增加以下代码:
authenticationSession.prefersEphemeralWebBrowserSession = true
这会防止前面遇到的在第2次或第三次测验在APP发动后快速登录时不提示输入用户凭据的问题。
时间短会话意味着 ASWebAuthenticationSession
不会缓存所有信息,并总会在会话开始时向客户询问凭据。
编译运行。
你仍是已登录的状况,由于 App 保存了拜访令牌和改写令牌。 点击顶部的 Sign Out 以清空令牌。 现在,测验登录时,会提示要输入你的 GitHub 用户名和暗码。 App 不会缓存任何之前登录的令牌,由于这是私有会话。
优秀!这看上去像是一个小问题,但关于安全方面,会有很大优点。
接下来要做什么?
能够点击该指南顶部或底部的 Download Materials 下载完整的工程文件。
做得很好!在该指南中,你学到了OAuth 的相关介绍,然后创建了你自己的运用 ASWebAuthenticationSession
授权的 GitHub App。
能够测验增加一些特性,如把令牌存储在钥匙串中加强存储令牌的方式,和增加更多的 GitHub API 恳求。
如果想阅读关于OAuth的更多令牌,拜访 IETF页面,它包括整个规范。 内容有些繁多,可是是很好的参考资料。
想了解ASWebAuthenticationSession
的细节和文档,拜访Apple 开发者文档。
想看在线视频课的话,查看Networking with URLSession.
如果有任何问题或建议,不要犹豫,在下面的论坛中与我们联系。