Swift實作Facebook、Google、Apple ID第三方登入功能

文章推薦指數: 80 %
投票人數:10人

Swift實作Facebook、Google、Apple ID第三方登入功能. 林怡瑄 2021/07/07 21:34:17. 5 1928. 現今APP的用途很廣泛,無論是生活還是娛樂用,很多APP採用了會員系統,讓 ... 當您輸入電子信箱、訂閱本公司之「電子報」時,我們會向您蒐集、處理、利用的個資為您的「電子信箱」以及「提交日期」,當您輸入電子信箱並送出時,即表示您同意我們使用您的個資,為保障您的權益,關於更多相關政策更新資訊,請務必閱讀我們的「隱私權政策」、「使用條款」及「免責聲明」。

如您不同意本網站之「隱私權政策」、「使用條款」及「免責聲明」,您可以隨時「取消訂閱」,謝謝您。

關閉 取消訂閱昕力資訊電子報 取消訂閱 關閉 關閉 是否確定取消註冊?將會永久刪除您在本站的帳號與資訊。

確定 取消 公告系統 × 目前無公告 首頁 App開發 iOS Swift實作Facebook、Google、AppleID第三方登入功能 iOS Swift Facebook Google Apple 第三方登入 Swift實作Facebook、Google、AppleID第三方登入功能 林怡瑄 2021/07/0721:34:17 5 1965 現今APP的用途很廣泛,無論是生活還是娛樂用,很多APP採用了會員系統,讓使用者必須使用一組帳號密碼來做登入,使用者方面可以記錄自己的喜好,而開發者也能保存使用者的資料。

但我們都知道要多記住一組帳密其實是很麻煩的事情,如果可以選擇使用Facebook、Google,或是iOS使用者必備的Apple帳號來作為會員登入,相信對諸多使用者來說都是很方便的,而開發者也能夠藉此取得更多資訊,真是一舉數得可喜可賀(?)。

這篇文章將會以這三個平台為例子,介紹開發者如何串接第三方登入,以及可以從中得到哪些使用者資料。

  一、使用Facebook作為第三方登入平台   以下會介紹詳細的使用步驟,亦可直接參閱官方說明文件: https://developers.facebook.com/docs/facebook-login/ios 我們先建立一個XCODE專案,接著至FB的開發者平台(https://developers.facebook.com/) 在註冊為開發者後,進入開發者首頁,點擊右上「我的應用程式」,並建立一個應用程式。

  選擇消費者。

  填入應用程式顯示名稱,注意不能直接使用FB、Facebook等包含官方名稱的文字,然後點擊建立應用程式。

  之後在左邊的側邊欄選取設定>基本資料,拉到最底下新增平台。

  選擇iOS。

  套件組和編號即為專案中的BundleID,以及記得把單一登入改為「是」,然後點擊右下方的「儲存變更」。

接著回到XCODE專案裡。

跟著官方文件在File>SwiftPackages>AddPackageDependency中,輸入框填入:https://github.com/facebook/facebook-ios-sdk 預設已為UptoNextMajor。

  選擇FacebookLogin後,點擊Finish,接著就可以看到左邊多了一欄。

接著我們設定專案,按照說明,在專案的Info.plist選擇以原始碼開啟(右鍵>OpenAs>SourceCode),在...中貼上代碼。

CFBundleURLTypes CFBundleURLSchemes fb2963XXXXXXXXXXX FacebookAppID 2963XXXXXXXXXXX FacebookDisplayName SocialLoginDemo LSApplicationQueriesSchemes fbapi fbapi20130214 fbapi20130410 fbapi20130702 fbapi20131010 fbapi20131219 fbapi20140410 fbapi20140116 fbapi20150313 fbapi20150629 fbapi20160328 fbauth fb-messenger-share-api fbauth2 fbshareextension 2963開頭的那串數字請換成自己的應用程式編號,在FB的開發者頁面上方可以找到。

SocialLoginDemo也要換成自己在FB建立的應用程式名稱(非XCODE專案名稱)。

  再來到AppDelegate.swift裡,把裡面的程式碼直接改為下面這段: importUIKit importFacebookLogin @UIApplicationMain classAppDelegate:UIResponder,UIApplicationDelegate{ funcapplication(_application:UIApplication,didFinishLaunchingWithOptionslaunchOptions:[UIApplication.LaunchOptionsKey:Any]?)->Bool{ ApplicationDelegate.shared.application(application,didFinishLaunchingWithOptions:launchOptions) returntrue } funcapplication(_app:UIApplication,openurl:URL,options:[UIApplication.OpenURLOptionsKey:Any]=[:])->Bool{ ApplicationDelegate.shared.application(app,open:url,sourceApplication:options[UIApplication.OpenURLOptionsKey.sourceApplication]as?String,annotation:options[UIApplication.OpenURLOptionsKey.annotation]) } }   這段的作用,讓我借用一下官方文件說明: 『此程式碼會在應用程式啟動時初始化SDK,並在執行「登入」或「分享」動作時,讓SDK處理原生Facebook應用程式的結果。

』   另外在SceneDelegate.swift中,先importFBSDKCoreKit後,加入以下程式碼: funcscene(_scene:UIScene,openURLContextsURLContexts:Set){ guardleturl=URLContexts.first?.urlelse{return} ApplicationDelegate.shared.application(UIApplication.shared,open:url,sourceApplication:nil,annotation:[UIApplication.OpenURLOptionsKey.annotation]) } 這段程式碼將處理開啟網址的功能。

  再來是置入按鈕的部分,官方有提供按鈕的圖示,如果要直接使用的話,在ViewController裡,先importFacebookLogin,並在viewDidLoad裡放進程式碼: letloginButton=FBLoginButton() loginButton.center=view.convert(CGPoint(x:view.center.x,y:300),from:self.view) view.addSubview(loginButton)   不過我這次自己做了三個按鈕。

所以我在按鈕裡放入: letloginManager=LoginManager() loginManager.logIn(permissions:[.publicProfile,.email],viewController:nil){loginResultin switchloginResult{ case.failed(leterror): print(error) case.cancelled: print("-------Usercancelledlogin") case.success(granted:_,declined:_,token:_): print("-------Loggedin") } }   點擊按鈕即會出現:   在登入帳號後,會提醒使用者這個APP要求的權限,即為程式碼中permissions:[.publicProfile,.email]的部分,隨著要求權限的不同也會有不同提醒。

  需注意的地方是,目前可以直接取得的使用者資料只有公開檔案與電子信箱這兩種,其餘都需要經由FB官方審查,開發者可從使用者的帳號裡獲得的資訊可以參考官方網頁: https://developers.facebook.com/docs/permissions/reference 如果程式碼中有尚未審查的權限,會出現像這樣的警告。

FB的登入審查相關請見官方文件: https://developers.facebook.com/docs/facebook-login/permissions/review 官方會檢驗APP中是否真的需要使用到這些涉及隱私的權限,文件中有較詳細的說明可以參考。

  此外,我們需要檢查使用者的登入狀態,可以從AccessToken.current  是否有值來確認登入狀態,並且取得userID,例如加上這樣的程式碼: ifletaccessToken=AccessToken.current{ print("-----------userID:\(accessToken.userID)") print("-----------tokenString:\(accessToken.tokenString)") }else{ print("notlogin") }   因此我現在可以從log裡看到這樣的結果:   以及再加上這幾行,這樣就能看到已登入的使用者資訊: letrequest=GraphRequest.init(graphPath:"me",parameters:["fields":"name,email"]).start{connection,result,errorin letresult=resultas!NSDictionary print(result) }     log印出結果:   如果需要登出的話,在登出的地方加上loginManager.logout()就可以了,這樣就完成使用Facebook第三方登入的功能啦,這邊僅列出最基本的流程,其餘的操作請至FB的開發者平台研究囉。

    二、使用Google作為第三方登入平台   FB的部分結束了,接著來實作Google的第三方登入,他的官方文件在這邊:https://developers.google.com/identity/sign-in/ios/start-integrating 下面也會每個步驟逐一截圖說明。

  取得GoogleSign-inSDK的方式,官方建議使用CocoaPods安裝(pod'GoogleSignIn') ,雖然也可以直接下載,不過我這邊就照著建議的方式吧,使用CocoaPods的過程就先省略了,網路上有很多的教學。

  安裝完後,改開.xcworkspace結尾的檔案,按照說明我們需要取得OAuth客戶端ID。

記得先複製一下ClientID,然後貼到專案裡TARGETS-Info,新增一項URLTypes。

  這邊要注意的是,我們剛剛複製的ClientID在URLSchemes前後是反過來的,需要調換順序,前面是com.googleusercontent.apps,後面就直接貼上即可。

    接著寫一點程式碼,在AppDelegate.swift中importGoogleSignIn,並在AppDelegate的類別中加入GIDSignInDelegate。

classAppDelegate:UIResponder,UIApplicationDelegate,GIDSignInDelegate{   在application:didFinishLaunchingWithOptions:方法中加入: GIDSignIn.sharedInstance().clientID="你的ClientID" GIDSignIn.sharedInstance().delegate=self     在application:openURL:options:方法中也加入: returnGIDSignIn.sharedInstance().handle(url)   此外,為了支援iOS8以下版本,官方建議加入已棄用的application:openURL:sourceApplication:annotation:方法,但如果APP本身沒打算支援較低的版本,可以不用加入這一段。

funcapplication(_application:UIApplication, openurl:URL,sourceApplication:String?,annotation:Any)->Bool{ returnGIDSignIn.sharedInstance().handle(url) }     在剛剛加入GIDSignInDelegate時,XCODE應該會出現要求增加協議的警告,需要定義didSignInFor這個方法,所以在底下加入: funcsign(_signIn:GIDSignIn!,didSignInForuser:GIDGoogleUser!,withErrorerror:Error!){ ifleterror=error{ if(errorasNSError).code==GIDSignInErrorCode.hasNoAuthInKeychain.rawValue{ print("Theuserhasnotsignedinbeforeortheyhavesincesignedout.") }else{ print("\(error.localizedDescription)") } return } //Performanyoperationsonsignedinuserhere. letuserId=user.userID//Forclient-sideuseonly! letidToken=user.authentication.idToken//Safetosendtotheserver letfullName=user.profile.name letgivenName=user.profile.givenName letfamilyName=user.profile.familyName letemail=user.profile.email }   再來是ViewController的部分,一樣先importGoogleSignIn,在viewDidLoad加入: GIDSignIn.sharedInstance()?.presentingViewController=self GIDSignIn.sharedInstance()?.restorePreviousSignIn()   最後是按鈕,我在自定義的按鈕裡加入這一行: GIDSignIn.sharedInstance().signIn() 上面是處理登入的部分,如果要登出的話就是: GIDSignIn.sharedInstance().signOut()   來看一下結果。

到這邊,使用者已經完成了登入的過程,開發者若要取得使用者資訊,可以從GIDGoogleUser中獲得。

官方的教學是把這段程式碼放在AppDelegate裡,如果需要呈現在畫面上,可以傳值到ViewController裡,或是直接在ViewController裡加入GIDSignInDelegate。

  官方文件中列出了一些可能會使用到的基本資料,如使用者ID,IDToken、姓名、email等等,直接從log印出來看看,我把程式改成這樣: ifletuserId=user.userID{ print("---------\(userId)") }//Forclient-sideuseonly! ifletidToken=user.authentication.idToken{ print("---------\(idToken)") }//Safetosendtotheserver ifletfullName=user.profile.name{ print("---------\(fullName)") } ifletemail=user.profile.email{ print("---------\(email)") }   印出來的結果: 以上到這邊是Google第三方登入的部分,更多的應用可以參考官方文件。

    三、使用AppleID作為第三方登入平台   對iOS使用者來說,使用AppleID登入或許是目前最安全的方式,開發者只會得到使用者的名字以及email,在登入時若選擇「隱藏我的電子郵件」,則開發者只會看到Apple幫忙建立的一組對應的、由系統產生的專屬帳號(網域為privaterelay.appleid.com),在保護隱私上更為徹底。

  接著來著手操作吧,首先至Signing&Capacilities中,新增Capability。

(附註說明,如果不是有加入開發者計劃或是企業的Apple帳號的話,Capability裡是不會有SigninwithApple這個選項的喔) 接著回到ViewController,先importAuthenticationServices,然後在自定義的按鈕裡加上: letprovider=ASAuthorizationAppleIDProvider() letrequest=provider.createRequest() request.requestedScopes=[.fullName,.email] letauthorizationController=ASAuthorizationController(authorizationRequests:[request]) authorizationController.delegate=self authorizationController.performRequests() 到這邊會出現一個錯誤提示,要求加入ASAuthorizationControllerDelegate,所以要加一個extension,連帶放入這些程式: extensionViewController:ASAuthorizationControllerDelegate{ funcauthorizationController(controller:ASAuthorizationController,didCompleteWithAuthorizationauthorization:ASAuthorization){ ifletcredential=authorization.credentialas?ASAuthorizationAppleIDCredential{ letuserId=credential.user letfullname=credential.fullName letemail=credential.email letidToken=credential.identityToken print("---------\(userId)") print("---------\(fullname)") print("---------\(email)") print("---------\(idToken)") } } funcauthorizationController(controller:ASAuthorizationController,didCompleteWithErrorerror:Error){ print(error.localizedDescription) } }   Error的部分也可以用switch去細分為不同的case,在ASAuthorizationError裡面可以看到failed、canceled等等的狀態,可以個別判斷為何種錯誤。

  之後來試跑看看,我是使用模擬器,前面的步驟沒有問題: 就沒有然後了,點下Contunue以後進入無止盡的轉圈圈。

後來搜尋了一下,在一年前也有人抱怨過這個問題,關於在iOS14版本的模擬器會出現無法登入AppleID的狀況: https://developer.apple.com/forums/thread/651533 不過底下有人提供解法,先去下載13.7版本的模擬器,並把APP的支援版本改成13.6或以下。

再運行一次看看。

成功了!並且可以看到,在我選擇了HideMyEmail之後,我log接收到的就是一組專屬的英數字帳號。

  最後稍微說一下那個836bytes,他的格式是個有時效性的JWT(JSONWebToken),寫成base64的編碼,我把程式改成: guardletidToken=credential.identityTokenelse{return} print("---------\(String(data:idToken,encoding:.utf8))")   會得到這一大串是由Header、Payload、Signature所組成。

有了IdentityToken可以向server驗證token是否過期,流程是這樣: 至於驗證token的方法請參考官方文件: https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user 四、實際應用 在討論實際應用之前,先回顧一下開發者可以從這三個平台獲取的資料。

  Google和Apple能獲取的資料較為基本,前者能拿到的是姓名、頭像,以及電子信箱;Apple能拿到的東西是姓名與電子信箱(使用者可以選擇顯示為中介mail)。

Facebook能拿的東西就很多了,除了基本的名稱、頭像、電子信箱外,還可能取得使用者的眾多個人資料,例如性別、年齡、居住地、教育狀況,甚至是朋友名單(限使用同APP)、點過讚的粉絲專頁、貼文、影片等,畢竟比起其他兩者,FB是社群網站,能掌握的東西多得多。

  不過綜合上述三種平台來看,開發者提供讓使用者以第三方平台作為快速註冊及登入,最方便的就是能快速取得使用者的名字或電子信箱,可以直接拿來作為使用者的代稱,例如在登入以後可以直接從第三方平台拿到的名字稱呼使用者,然後再提供一個可以修改的地方;也可以收集到使用者信箱,作為行銷推廣使用等等。

  或者最常見的,是利用分享的功能,在取得貼文的權限以後貼到使用者的公開頁面,藉以達到宣傳的效果,或是列出同樣有使用同個APP的朋友等,這兩點我們在很多的手遊APP裡應該都能看到有類似的機制,比如說請朋友送體力之類的,雖然要求這些權限需要通過FB的審核,但只要附上完整的說明,我想有那麼多前輩APP在先了,應該不會被特別刁難(大概吧)(欸)。

  不過有個重要的事情,根據文件:https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple APP中如果提供第三方登入,除非是教育類,或者是企業內部使用的情形,否則一定要加入SigninwithApple的部分,所以如果要在iOS的APP中加入任何的第三方平台作為登入,勢必也得加上Apple登入。

  但以我個人經驗,如果是打算以第三方登入所取得的信箱資料作為ID的話,最好不要讓使用者在其他地方有需要填ID的時候,一律在APP內作業,因為在選擇了隱藏信箱後ID就會變成了那一串亂碼般的英數字,然而一些遊戲的獎勵是在網頁上操作,我根本不記得我的代理mail是什麼最後只好重新註冊一個,還好還沒玩多久⋯⋯(扯遠了)。

不過整體來說AppleID是很方便,還可以用TouchID或FaceID快速登入,如果只是單純作為APP註冊的話,我覺得對iOS使用者來說是最好的選擇了。

  總之,以上就是目前最普遍使用的三種第三方登入的說明,這邊都只列出基本使用的方法,如果有興趣想活用在更多方面,請至各官方文件進行探索囉。

  參考資料: https://developers.facebook.com/docs/facebook-login/ios https://developers.google.com/identity/sign-in/ios/start-integrating https://developer.apple.com/documentation/authenticationservices/implementing_user_authentication_with_sign_in_with_apple https://developer.apple.com/forums/thread/651533   5 點數申請 文章標題 : Swift實作Facebook、Google、AppleID第三方登入功能 申請項目 : 檔案上傳 請選擇審查人員 暫存 確認 林怡瑄 相關文章 Swift實作Facebook、Google、AppleID第三方登入功能 第一次使用CoreData就上手 TableView實現畫線、自動捲軸、取得座標位置 串接第三方API,解析JSON資料,轉換成自訂型別顯示 Swift簡易Lottie動畫運用 SwiftJSONDecodewith@propertyWrapper 最新文章 陣列排序Sort()與C3.js視覺資料處理 Xamarin.Forms繫結原生程式庫 EntityFrameworkCore下使用SQL方式取得資料庫的特定欄位資料 AngularRouterGuard 關聯式資料庫讀寫分離及分表分庫 Async/awaithell 最熱門文章 同作者文章 確定 取消 × 登入



請為這篇文章評分?