Apple login

目前Apple login 在App Store審核時并不是強制集成的,但是只要App 集成任何一個其他的第三方認(rèn)證登錄(微信、Google等)就必須也得集成Apple login,這是Apple 的強制要求,否則審核時App 會被拒絕。 Apple Login 官方文檔

Apple login 是iOS 13 后才支持的API也就是說iOS 13 以前的系統(tǒng)是不能集成Apple login的,下面具體介紹一下集成Apple login 需要做哪幾方面的工作。

準(zhǔn)備工作

  • Xcode 需要升級到 11 以上的版本
  • iOS 13 以上系統(tǒng)的測試設(shè)備
  • 開發(fā)者需要到Apple 開發(fā)者賬號下勾選上Sign In with Apple 登錄選項,重新下載Profile文件。
    image.png

    1.登錄Apple開發(fā)者賬號
    2.選擇左邊Identifier 欄目,在右側(cè)選擇要開通Sign In with Apple的Identifiers 點擊打開,下拉找到Sign In with Apple勾選上。
    3.點擊右上角save保存會出現(xiàn)Modify App Capabilities彈窗,點擊Confirm。
    開啟后 profile 將失效需要重新編輯 profile 文件
    4.在xcode項目中開啟sign in with apple
    image.png

App 端開發(fā)工作

添加依賴庫

image.png

創(chuàng)建Apple Login Button

Apple 提供了官方的Sign In with Apple button,當(dāng)然這個按鈕也可以自定義,自定義按鈕規(guī)則
代碼

let authorizationButton = ASAuthorizationAppleIDButton()
        authorizationButton.addTarget(self, action: #selector(handleAuthorizationAppleIDButtonPress), for: .touchUpInside)
        if #available(iOS 13.0, *) {
            self.loginProviderStackView.addArrangedSubview(authorizationButton)
        }

Button 的type有登錄類型ASAuthorizationAppleIDButtonTypeSignIn和注冊類型ASAuthorizationAppleIDButtonTypeSignUp(只能在13.2+有效,13.0-13.2需要自定義)。
Button的style的有幾種類型,但都是黑白配。

向Apple 發(fā)起請求

蘋果還把 iCloud KeyChain password 集成到了這套 API 里,我們在使用的時候,只需要在創(chuàng)建 request 的時候,多創(chuàng)建一個 ASAuthorizationPasswordRequest,這樣如果 KeyChain 里面也有登錄信息的話,可以直接使用里面保存的用戶名和密碼進行登錄。

 func handleAuthorizationAppleIDButtonPress() {
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
        
        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    }

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        switch authorization.credential {
        case let appleIDCredential as ASAuthorizationAppleIDCredential:
            
            // Create an account in your system.
            let userIdentifier = appleIDCredential.user
            let fullName = appleIDCredential.fullName
            let email = appleIDCredential.email
            let authorizationCode = appleIDCredential.authorizationCode
            UIPasteboard.general.string = String.init(data: authorizationCode!, encoding: String.Encoding.utf8)
            
            // For the purpose of this demo app, store the `userIdentifier` in the keychain.
            self.saveUserInKeychain(userIdentifier)
            
            // For the purpose of this demo app, show the Apple ID credential information in the `ResultViewController`.
            self.showResultViewController(userIdentifier: userIdentifier, fullName: fullName, email: email)
        
        case let passwordCredential as ASPasswordCredential:
        
            // Sign in using an existing iCloud Keychain credential.
            let username = passwordCredential.user
            let password = passwordCredential.password
            
            // For the purpose of this demo app, show the password credential as an alert.
            DispatchQueue.main.async {
                self.showPasswordCredentialAlert(username: username, password: password)
            }
            
        default:
            break
        }
    }

基本流程:向Apple 發(fā)送認(rèn)證請求,請求返回結(jié)果后,用結(jié)果信息中authorizationCode向App的服務(wù)端接口發(fā)送用戶認(rèn)證請求進行用戶登錄驗證。初次登錄時可以讓用戶編輯顯示的用戶名及是否隱藏郵箱,第二次登錄之后用戶進行認(rèn)證即可。蘋果官方開發(fā)文檔 蘋果官方完成demo
注意:獲取的用戶信息中:email、NSPersonNameComponents對象所有屬性是只有第一次請求的時候才會返回,之后就算 停止使用 Apple ID 再重新授權(quán)都不會返回用戶信息。
authorizeCredential.user 是用戶的唯一ID,同一個開發(fā)者賬號下這個ID一致。
authorizeCredential.authorizationCode驗證碼,每次返回的不一樣,看服務(wù)端使用那種驗證方式而定是否使用。
authorizeCredential.identityToken用戶的驗證token,有一定的有效期,到期后會刷新。
Apple建議將用戶ID保存在鑰匙串中以便在App啟動的時候進行檢查AppleID的登錄狀態(tài)。
用戶注銷 AppleId 或 停止使用 Apple ID 的狀態(tài)處理

服務(wù)端驗證

服務(wù)端驗證分兩種驗證方式:一種是驗證碼驗證、一種是JWT驗證。具體詳見Apple 官方文檔:https://developer.apple.com/documentation/signinwithapplerestapi

手機端需要提交 user 、authorizationCode 、 identityToken 字段信息(code和token字段蘋果返回的是 base64 Data 形式,手機端可以先轉(zhuǎn)換 base64 字符串之后在給服務(wù)器)到服務(wù)器。然后服務(wù)器通過 https://appleid.apple.com/auth/token 該接口,并拼接對應(yīng)參數(shù)去驗證,接口相關(guān)信息蘋果有提供。
后端接口需要的參數(shù)

  • Client_id:App 的BundleID
  • client_secret:后臺生成的JWT key。
  • Code:客戶端傳過的authorizationCode
  • grant_type:常量authorizationCode

參數(shù)的獲取方法:
登錄Apple開發(fā)者賬號-menbership 獲取teamid ;
創(chuàng)建private_key:進入證書欄certificates、IDs&Profiles,選擇keys標(biāo)簽(如果沒有keys標(biāo)簽,可能是您登錄的Apple開發(fā)者賬號不是超管賬號,沒有權(quán)限。)-現(xiàn)在添加--給key命名并選擇對應(yīng)的bundleid。
注:該private_key只能下載一次。
根據(jù)Apple返回的結(jié)果中sub字段即是用戶的ID,可以和手機端的user字段對比驗證。

client_secret 的生成

打開終端cd ‘文件路徑’, touch secret_gen.rb 這個命令執(zhí)行完成后就可以看到這個文件,打開文件把下面的代碼粘貼進去配置相應(yīng)的信息,繼續(xù)終端步驟 ruby secret_gen.rb

require "jwt"

key_file = "Path to the private key"
team_id = "Your Team ID"
client_id = "Your App Bundle ID"
key_id = "The Key ID of the private key"
validity_period = 180 # In days. Max 180 (6 months) according to Apple docs.

private_key = OpenSSL::PKey::EC.new IO.read key_file

token = JWT.encode(
{
iss: team_id,
iat: Time.now.to_i,
exp: Time.now.to_i + 86400 * validity_period,
aud: "[https://appleid.apple.com](https://links.jianshu.com/go?to=https%3A%2F%2Fappleid.apple.com)",
sub: client_id
},
private_key,
"ES256",
header_fields=
{
kid: key_id
}
)
puts token
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內(nèi)容