如何通過(guò) ASWebAuthenticationSession 獲取身份驗(yàn)證 Code 碼
本文轉(zhuǎn)載自微信公眾號(hào)「網(wǎng)羅開(kāi)發(fā)」,作者展菲。轉(zhuǎn)載本文請(qǐng)聯(lián)系網(wǎng)羅開(kāi)發(fā)公眾號(hào)。
1. 前言
項(xiàng)目中需要實(shí)現(xiàn) GitHub、Google、Apple 登錄,實(shí)現(xiàn)第三方登錄方案有 3 種:
- 集成第三方一鍵登錄
- 分別集成 GitHub、Google、Apple 登錄 SDK
- 不集成 SDK 打開(kāi)瀏覽器登錄
今天來(lái)講一下不集成 SDK 打開(kāi)瀏覽器登錄獲取身份驗(yàn)證。
這需要使用 ASWebAuthenticationSession 獲取身份驗(yàn)證 code 碼。
網(wǎng)站登錄身份驗(yàn)證邏輯:
一些網(wǎng)站作為一種服務(wù)提供了一種用于驗(yàn)證用戶(hù)身份的安全機(jī)制。
當(dāng)用戶(hù)導(dǎo)航到站點(diǎn)的身份驗(yàn)證URL時(shí),站點(diǎn)將向用戶(hù)提供一個(gè)表單以收集憑據(jù)。
驗(yàn)證憑據(jù)后,站點(diǎn)通常使用自定義方案將用戶(hù)的瀏覽器重定向到指示身份驗(yàn)證嘗試結(jié)果的URL。
2. 不集成 SDK 打開(kāi)瀏覽器登錄
你可以通過(guò)使用指向身份驗(yàn)證網(wǎng)頁(yè)的 URL 初始化實(shí)例來(lái)在應(yīng)用程序中使用網(wǎng)絡(luò)身份驗(yàn)證服務(wù)。
該頁(yè)面可以是你維護(hù)的頁(yè)面,也可以是由第三方操作的頁(yè)面。
通過(guò)打開(kāi)瀏覽器登錄并獲取身份驗(yàn)證 code 碼,可以分為兩種情況:
- 一種情況是在 App 內(nèi)部打開(kāi)瀏覽器獲取身份驗(yàn)證
- 一種是打開(kāi)手機(jī)自帶瀏覽器獲取身份驗(yàn)證
嘗試第一種情況之后 GitHub 和 Apple 均可以正常打開(kāi)瀏覽器并且成功登錄拿到身份驗(yàn)證碼。
但是 Google 提示在 App 內(nèi)部打開(kāi)登錄頁(yè)面是不安全的,因此只能選擇第二種方式。
3. 打開(kāi)手機(jī)自帶瀏覽器獲取身份驗(yàn)證
3.1 配置 URL Types
建議使用 bundle id 保證唯一性。
3.2 定義全局變量
- var session: ASWebAuthenticationSession!
var session : ASWebAuthenticationSession! 需要設(shè)置為全局變量,設(shè)置為局部變量會(huì)被釋放掉導(dǎo)致彈框閃現(xiàn)。
3.3 獲取身份驗(yàn)證 code 碼
- func oauthLogin(type: String) {
- // val GitHub、Google、SignInWithApple
- let redirectUrl = "配置的 URL Types"
- let loginURL = Configuration.shared.awsConfiguration.authURL + "/authorize" + "?identity_provider=" + type + "&redirect_uri=" + redirectUri + "&response_type=CODE&client_id=" + Configuration.shared.awsConfiguration.appClientId
- session = ASWebAuthenticationSession(url: URL(string: loginURL)!, callbackURLScheme: redirectUri) { url, error in
- if error != nil {
- return
- }
- if let responseURL = url?.absoluteString {
- let components = responseURL.components(separatedBy: "#")
- for item in components {
- if item.contains("code") {
- let tokens = item.components(separatedBy: "&")
- for token in tokens {
- if token.contains("code") {
- let idTokenInfo = token.components(separatedBy: "=")
- if idTokenInfo.count > 1 {
- let code = idTokenInfo[1]
- print("身份驗(yàn)證 code 碼: \(code)")
- return
- }
- }
- }
- }
- }
- }
- }
- session.presentationContextProvider = self
- session.start()
- }
這里面有兩個(gè)參數(shù),一個(gè)是 redirectUri,一個(gè)是 loginURL。
redirectUri 就是 3.1 配置的白名單,作為頁(yè)面重定向的唯一標(biāo)示。
loginURL 是由 5 塊組成:
- 服務(wù)器地址:Configuration.shared.awsConfiguration.authURL + "/authorize"
- 打開(kāi)的登錄平臺(tái):identity_provider = "GitHub"
- 重定向標(biāo)識(shí):identity_provider = "配置的 URL Types"
- 相應(yīng)類(lèi)型:response_type = "CODE"
- 客戶(hù)端 ID:client_id = "服務(wù)器配置"
回調(diào)中的 url 包含我們所需要的身份驗(yàn)證 code 碼,需要層層解析獲取 code。
3.4 指定授權(quán)界面顯示的 window
告訴代理應(yīng)該在哪個(gè) window 展示授權(quán)界面給用戶(hù)
- #pragma mark - ASAuthorizationControllerPresentationContextProviding
- extension ViewController: ASWebAuthenticationPresentationContextProviding {
- func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
- return self.view.window ?? ASPresentationAnchor()
- }
- }