Mac 應(yīng)用接入Google 第三方登錄
所有的第三方登錄,本質(zhì)上應(yīng)該都是 OAuth 授權(quán)套么。
OAuth授權(quán)共有四種方式医寿,其中最常見(jiàn)的是授權(quán)碼授權(quán)
- Code 授權(quán)碼,先獲取 授權(quán)碼镊辕,再拿授權(quán)碼獲取 token(最常用)
- 隱式授權(quán)-直接獲取 token
- 帳號(hào)密碼式授權(quán)-直接獲取 token (用戶極度信任才會(huì)把帳號(hào)密碼交給你)
- 憑證授權(quán)-直接獲取 token
而 OAuth 授權(quán),需要用戶同意授權(quán)蚁袭,我們的應(yīng)用向第三方申請(qǐng) 授權(quán)碼征懈,拿到授權(quán)碼之后,再去請(qǐng)求 accessToken揩悄,之后去第三方獲取信息卖哎,帶上這個(gè) token 即可。
而通常,第三方應(yīng)用需要知道誰(shuí)在請(qǐng)求獲取授權(quán)碼亏娜,所以我們需在第三方注冊(cè)應(yīng)用焕窝,獲取客戶端 id 和密碼,用于讓第三方確認(rèn)是誰(shuí)在請(qǐng)求照藻。
請(qǐng)求授權(quán)需要授權(quán)那些信息袜啃,這就需要 scope 來(lái)控制汗侵。
授權(quán)之后幸缕,需要跳轉(zhuǎn)回我們的應(yīng)用程序。通常使用 redirectURI 晰韵,而對(duì)于安裝在計(jì)算上的原生應(yīng)用发乔,又有好幾種方式,關(guān)于應(yīng)用自定義 Scheme 對(duì)有些授權(quán)商來(lái)說(shuō)雪猪,有著嚴(yán)格的規(guī)定栏尚,而有些則很寬松。
雖然OAuth 流程都差不多只恨,但是不同的授權(quán)服務(wù)商的實(shí)現(xiàn)不同译仗,所以還是要仔細(xì)閱讀文檔以及所使用的第三方庫(kù),還是第三方數(shù)據(jù)請(qǐng)求請(qǐng)求的API 接口官觅,用來(lái)獲取想要的信息纵菌。
我覺(jué)得Google 的第三方登錄,對(duì) Mac 本地應(yīng)用來(lái)說(shuō)休涤,難度比 iOS 和安卓 這些移動(dòng)應(yīng)用要大咱圆。當(dāng)然最簡(jiǎn)單的是網(wǎng)頁(yè)端。這個(gè)是谷歌的官網(wǎng)文檔:https://developers.google.com/identity/protocols/OAuth2
1. 去 Google 開(kāi)發(fā)平臺(tái)注冊(cè)應(yīng)用
點(diǎn)擊 注冊(cè)地址 然后再點(diǎn)擊新建功氨,新建一個(gè)項(xiàng)目
2. 創(chuàng)建憑證
選擇 客戶端 id "OAuth client ID"
創(chuàng)建的時(shí)候序苏,可能需要填寫OAuth同意屏幕,這里暫時(shí)只需要填寫應(yīng)用名稱即可捷凄。
類型選擇其他 Other
創(chuàng)建成功之后忱详,記錄下 客戶端 id 和 秘鑰。這個(gè)很重要跺涤。
3. 配置項(xiàng)目
在此踱阿,我們使用第三方庫(kù)來(lái)處理 Google 第三方登錄。
所用的第三方庫(kù)為:GTMAppAuth
使用 pod 引入項(xiàng)目 pod 'GTMAppAuth'
pod install
然后跟著第三方庫(kù)的說(shuō)明走就可以了钦铁。
例如獲取 token
let kClientID = google["ClientID"]!
let kClientSecret = google["ClientSecret"]!
let redirectURI = URL(string:google["redirectURI"]!)!
configuration = GTMAppAuthFetcherAuthorization.configurationForGoogle()
let request = OIDAuthorizationRequest.init(configuration: configuration!, clientId: kClientID, clientSecret: kClientSecret, scopes: ["openid","profile"], redirectURL: redirectURI, responseType: "code", additionalParameters: nil)
(NSApp.delegate as! AppDelegate).currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, callback: { (authState, error) in
if let auth = authState {
self.authorization = GTMAppAuthFetcherAuthorization.init(authState: auth)
log.info("get access token :\(auth.lastTokenResponse!.accessToken!)")
self.getUserInfo()
}else {
if let err = error {
log.error("Authorization error:\(err.localizedDescription)")
}
self.authorization = nil
}
})
注意配置好 客戶端 id 秘鑰软舌,以及是 回調(diào)URI
在我們的項(xiàng)目中使用回調(diào) URI,需要在 info 欄配置URL Schemes
而這個(gè)URL Schemes規(guī)則應(yīng)該是是Google 定好的 (我從這篇文檔中推測(cè)的牛曹,當(dāng)然也可能此第三方庫(kù)做了處理)佛点,我們不能隨意填寫。Google 返回的客戶端 id,反著寫就好了超营。
例如:客戶端 id: 279659059126-0d06hf001bm5bb9p2aj6sqjvjgp5smj2.apps.googleusercontent.com
則 scheme定義:com.googleusercontent.apps.279659059126-0d06hf001bm5bb9p2aj6sqjvjgp5smj2而真實(shí)的回調(diào) URI 也是 Google 規(guī)定好的鸳玩,scheme 之后 加上 ":/oauthredirect",注意是一個(gè)斜杠演闭,而不是兩個(gè)不跟。
跳轉(zhuǎn) URI:com.googleusercontent.apps.279659059126-0d06hf001bm5bb9p2aj6sqjvjgp5smj2:/oauthredirect
配置好之后,應(yīng)該就可以了米碰。
此外窝革,還需要在 appdelegate 中做一些處理。當(dāng)授權(quán)后跳轉(zhuǎn)到我們的應(yīng)用程序吕座,需要處理一下:
func applicationDidFinishLaunching(_ aNotification: Notification) {
thirdPartOpenURLHandle()
}
func thirdPartOpenURLHandle() {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(handleGetURLEvent(event:with:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
@objc func handleGetURLEvent(event:NSAppleEventDescriptor, with replyEvent:NSAppleEventDescriptor) {
if let urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue , let url = URL(string: urlString) {
currentAuthorizationFlow?.resumeExternalUserAgentFlow(with: url)
}
}