使用 React Native 與 Amazon Cognito 實作 Google & Facebook 登入的功能

Standard

最近開始接觸 React Native 的專案了,能用前端技術跟知識同時開發 iOS/Android App 滿新奇的!雖然缺乏原生 App 的知識讓我踩了不少坑,其中不少還是非常低能的坑 XD!

這次實作的任務是要在 App 加上 Google/Facebook 登入的功能,而會員系統是建構在 Amazon Cognito 上面的,再加上 React Native 的相關套件 – react-native-facebook-loginreact-native-google-signin 來實作 App 中的登入功能。其中有些設定上的眉角讓我花了不少時間嘗試,所以整理成本篇的筆記備忘囉~


本文大綱

本篇文章滿長的,所以先整理大綱在此,了解一下會介紹到的部份:

  • 本文的套件版本
  • AWS SDK React Native 與 Amazon Cognito
  • react-native-facebook-login
  • react-native-google-signin
  • 繼續未完的 Amazon Cognito 設定
  • 前端程式
  • 疑難排解
  • 用 Amazon Lambda 來做 Serverless API
  • Amazon API Gateway
  • 在 App 端補上註冊(register)的 function
  • Source Code
  • 參考資料

本文的套件版本

由於這是個升版可能就變天的世代,所以開始之前先將相關版本列於下方:

AWS SDK React Native 與 Amazon Cognito

首先,要建構會員系統的話,依過去的經驗,有很多部分要處理,像是寫會員註冊、忘記密碼、認證、更新資料等後端程式,還要建會員資料庫、思考怎麼跟第三方社群登入(像是本文主要目的的 Google、Facebook 登入)串接、怎麼讓桌機與手機都能 work… 等一拖拉庫的事情。雖然要一個個自己來也是可以,但像前端工程師如我,可能就要花上不少時間了,也有時間成本的考量,而 Amazon Cognito 提供了一套不錯的跨裝置會員系統解決方案。

Amazon Cognito 讓您輕鬆新增使用者註冊與登入功能到行動應用程式與 Web 應用程式。使用 Amazon Cognito,您也可以選擇透過 Facebook、Twitter 或 Amazon 等社交身分供應商、利用 SAML 身分解決方案,或使用自己的身分系統來驗證使用者。除此之外,Amazon Cognito 可讓您將資料儲存在使用者的本機裝置,這允許應用程式即使在裝置離線時也能運作。然後,您可以同步使用者不同裝置之間的資料,無論他們使用哪部裝置,都能獲得一致的應用程式體驗。

而此次的任務就是在 React Native 的架構下要導入以 Cognito 為基礎的社群會員(Google 與 Facebook)登入流程,當然也可以選用非第三方的身分認證,像是手機、E-mail 認證等方式,不過就不在本文介紹範圍中了。首先,假設我們已經設定好一個基本的 React Native 的專案了,接下來就要安裝相關的套件 – aws-sdk-react-native

註:其實在本文撰寫過程中,官方就更新 aws-sdk-react-native 的說明了,是說官方比較推薦去使用 AWS JavaScript SDK with React Native support,不過本文還是維持原本使用的 aws-sdk-react-native 這套進行實作,因為這套實在太多坑啦!就算看了說明檔還是看不懂怎麼使用!😱


以下流程主要是參考 @chunghe 在該 repo Issues 貼出的 detail step-by-step guide 進行步驟:

打包

  1. 首先要做的是自己打包(pack)一份 aws-sdk-react-native,請先下載 AWS Mobile iOS SDK 2.4.16 版官網下載頁目前放上的 iOS 2.5+ 版跟本文流程不相容),然後解壓縮
  2. 然後把 aws-sdk-react-native 專案下載下來,可以用 git clone https://github.com/awslabs/aws-sdk-react-native.git
  3. 把步驟 1 中解壓縮的資料夾打開,進入 frameworks 資料夾,找到 AWSCore.framework,將它複製到 aws-sdk-react-native 資料夾中的 Core/src/ios/Frameworks/ 資料夾底下
  4. 然後 aws-sdk-react-native/Core/src/AWSCognitoCredentials.js 有個 JavaScript bug 😫 打包前要自己手動修正。請將第 48 行的:
    listener.addListener("LoginsRequestedEvent", async {callbackId} => {
    

    改為

    listener.addListener("LoginsRequestedEvent", async ({callbackId}) => {
    
  5. 接著進入 aws-sdk-react-native/Core/,鍵入以下指令進行打包(pack):
    npm pack
    
  6. 好了,打包完就有個名為 aws-sdk-react-native.tgz 的打包檔了,沒有操作錯誤的話,它大概有 8.3MB。接下來把它 copy 到專案目錄下並改個名字吧,我是放在 專案目錄/aws-sdk-react-native/ 底下,並更名為 aws-sdk-react-native-core-0.0.2-with-awscore-framework.tgz

安裝到專案中

  1. 透過 yarn 安裝到專案中:
    yarn add ./aws-sdk-react-native/aws-sdk-react-native-core-0.0.2-with-awscore-framework.tgz
    
  2. 然後 link 它:
    react-native link aws-sdk-react-native-core
    
  3. 打開專案的 Xcode 檔案(在 ios/ 底下可能是 xxx.news.xcodeproj,有用 Pods 的話就是 xxx.xcworkspace),確認 Targets 是目前的專案名稱:image

    然後切換到 General 的頁籤,往下捲動直到找到 Embedded Binaries,按下下方的 + 按鈕。

  4. 在新跳出的視窗中,點擊左下角的 Add Other...,尋找專案目錄底下 node_modules/aws-sdk-native-core/ios/Frameworks/ 中的 AWSCore.framework 檔案,選定之後按下 Open
  5. 在下一個跳出的視窗中,請確認 不要勾選 Destination: Copy items if needed 的選項,因為這個檔案已經在專案目錄的 node_modules/aws-sdk-native-core/ios/Frameworks/ 目錄底下囉。好了之後請按下 Finish

    2017-05-24 10 23 09

  6. 操作無誤的話會看到下圖這樣:

    image

  7. 接下來請切換到 Build Phases 頁籤,並點擊左上角的 + 按鈕,選擇 New Run Script Phase

    2017-05-24 10 24 23

  8. 請確認新增的 Run Script 區塊是在 Embed Frameworks 區塊之下的,不是的話請拖曳改變順序。然後展開 Run Script,確認 Shell/bin/sh,接著在下方文字框輸入:
    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework/strip-frameworks.sh"
    

    接著要確認下面四個部分 Show environment variables in build log 已勾選、Run script only when installing 未勾選、Input FilesOutput Files 都是空的。如圖:

    2017-05-23 8 41 04

  9. 最後,請切換至 Build Settings 頁籤,找到 Search Paths 底下的 Framework Search Paths(如果覺得選項太多不好找,可利用右上角的搜尋框),加入 $(SRCROOT)/../node_modules/aws-sdk-react-native-core/ios/Frameworks

    2017-05-23 8 10 40

    好了,這樣套件就安裝完成了,可以試著 Build 看看,若沒有遇到 Fail 的話應該就是沒問題的。

Amazon Cognito 設定

假設已經申請好 AWS 的帳號了,請連到 Amazon Cognito 開始接下來的步驟:

  1. 到首頁請選擇「開始使用 Amazon Cognito」,連過去之後又有兩顆按鈕,因為這次的任務是要用第三方社群身分驗證進行登入,所以選擇右邊的 Manage Federated Identities
  2. 點擊 Create new identity pool 建立新的身分池。
  3. 給這個 pool 一個名字吧,例如 My App。然後展開 Authentication providers,可以看到各式各樣的 providers,本例要設定的是 Facebook 與 Google,但是請 注意!若你有多個平台需要使用同一組 Google 身分,在 Google 的部份請透過 OpenId 進行設定喔!否則就會在不同平台登入的同一組 Google 帳號(例如 Web 跟 iOS 裝置登入的 Google 帳號)會被視為不同的身分!
  4. 由於下面介紹 react-native-facebook-loginreact-native-google-signin 時,會介紹 Facebook 與 Google 應用程式的設定步驟,因此這邊就先跳過,只要知道之後會回來這邊設定 Facebook 與 OpenID 的部份即可。先留著這個視窗,晚點回來繼續完成。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *