HelloChunWei / blog

個人部落格,紀錄自己的知識
MIT License
7 stars 0 forks source link

Sign in with Apple 流程 #4

Open HelloChunWei opened 4 years ago

HelloChunWei commented 4 years ago

前言

2020/04 月過後,Apple 規定如果 APP 有所謂的第三方登入的話,必須要提供 Apple ID 登入這個選項,否則 APP 審核不會過。 詳細的規則在此:https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple

最近公司的 APP 正在從 webview 轉換到 Flutter 架構, 前陣子要送審第一版 Flutter 架構的App,才發現到這問題,所以只好又花一天的時間把 Sign in with Apple 做好。

前置準備

  1. 文件中可以知道我們要先讓我們的 APP 可以使用 Sign in with Apple 跟推播類似,所以不難。

  1. 之後開啟 Xcode 在專案上點選 Signing & Capabilities > + Capability > 加入 Sign in with Apple

在這裡基本上就已經把前置準備完成了,接下來就是實作到code上

流程

即使是用 Flutter 開發 App 不是用 Swift ,但我還是習慣會先把流程弄懂,Apple 的 framework 需要帶什麼參數,會回傳什麼東西出來,代表什麼意義。把這些都搞懂之後呢,在用 Flutter 的 package 加入到我們既有的專案。

Apple 很好心的弄了一個 Sample 給大家看,簡單說一下簡單的思路,

  1. 建立一個 Button (但button 的設計是有規則的)

  2. 點下去後呼叫Apple framework 登入流程 此時會看到使用者可以選擇要不要揭露自己的 Email 如果不揭露的話, Apple 會給一個新的Email XXXXX@privaterelay.appleid.com,寄 Email 到此信箱 Apple 會幫你直接轉寄到使用者,這樣就看不到使用者的真實Email

  3. 登入成功後 Apple framework 會回傳參數

那 Apple 到底會回傳什麼呢??從 Apple 的範例可以看到

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

有 userIdentifier, fullName, email,userIdentifier 應該專屬於自己 App 的User Id,也就是說,使用者如果都沒更換Apple ID的話,他登入就是會是同樣的 userIdentifier,FullName, email 應該就不用多解釋了。不過這兩個參數只有第一次登入時會回傳,第二次後就不會有了

不過 Apple 的範例只有做前端的部分,後端驗證不在此範例中,如果開發的需求只需要前端的話做到這邊即可,Apple 審核一樣會過。

後端

如果要用後端驗證的話,那到底要怎麼驗證?

文件知道,登入成功後不只會回傳 userIdentifier, fullName, email,還有 identityToken (JWT 格式), authorizationCode, identityToken 主要的功用是: 驗證此 token 是不是 Apple 所簽發的。

authorizationCode,就是利用 Apple restful API 取得 user 的相關資訊。

比較詳細的流程在此: document

要驗證 identityToken 的話,必須先從 Apple restful API 中取得她們的 public key 取得後再去驗證: document

  1. iss 會來自 https://appleid.apple.com
  2. aud 是自己的 client_id

authorizationCode 則是跟 Apple 交換 Access Token 以及 refresh token,以供未來呼叫 Apple restful 用 refesh token 可以換到 user 的 access token,目前我還不清楚 Access token,的其他用處,可能未來會像其他服務一樣提供更多的 API 呼叫,到時候就需要這 access token了。

Note: 如果使用者再次登入的話,產生了新的 identity token 的話 refresh token 是會失效的。document

結論

這大概是 Sign in with apple 的流程,如果想寄信到XXXXX@privaterelay.appleid.com 必須在此設定 domin ,然直接寄信的話是無法收到的。了解流程後,接下來就是把它應用在 Flutter 了,幸好 Flutter 有人有做 package 。所以串接起來不算太難。