AWS 入門
建置 Android 應用程式
使用 AWS Amplify 建立簡單的 Android 應用程式
單元 3:新增身份驗證
在本單元中,您將使用 Amplify CLI 和程式庫來設定應用程式,並新增身份驗證。
簡介
您將新增的下一個功能是使用者身份驗證。在本單元中,您將學習如何利用受管使用者身份供應商 Amazon Cognito 透過 Amplify CLI 和程式庫對使用者進行身份驗證。
您還將學習如何使用 Cognito 託管使用者界面來呈現整個使用者身份驗證流程,僅用幾行程式碼即可允許使用者進行註冊、登入和重置密碼操作。
使用「託管使用者界面」,意味著該應用程式利用 Cognito 網頁進行登入和註冊使用者界面流程。應用程式的使用者將重新定向至 Cognito 託管的網頁,並在登入後重新定向回該應用程式。當然,Cognito 和 Amplify 也支援本機 UI,您可以遵循以下研討會指導,進一步了解有關自訂身份驗證 UI 的資訊。
您將學到的內容
- 建立和部署身份驗證服務
- 設定您的 Android 應用程式以包括 Cognito 託管的 UI 身份驗證
主要概念
Amplify 程式庫 – Amplify 程式庫讓您可以透過 Web 或行動應用程式與 AWS 服務進行互動。
身份驗證 – 在軟體中,身份驗證是使用身份驗證服務或 API 驗證和管理使用者身份的過程。
完成時間
10 分鐘
使用的服務
實作
-
建立身份驗證服務
若要建立身份驗證服務,請開啟終端機,然後執行以下命令:
amplify add auth ? Do you want to use the default authentication and security configuration? Select Default configuration with Social Provider and press enter ? How do you want users to be able to sign in? Select the default Username and press enter ? Do you want to configure advanced settings? Select the default No, I am done and press enter ? What domain name prefix do you want to use? Select the default and press enter Enter your redirect signin URI: type gettingstarted:// and press enter ? Do you want to add another redirect signin URI? Select the default N and press enter Enter your redirect signout URI: type gettingstarted:// and press enter ? Do you want to add another redirect signout URI? Select the default N and press enter ? Select the social providers you want to configure for your user pool: do not select any provider and press enter
當您看到此訊息時,則會知道組態已設定成功 (資源的確切名稱會有所差異):
Successfully added resource androidgettingstartedfc5a4717 locally
-
部署身份驗證服務
現在已經在本機設定了身份驗證服務,我們可以將其部署至雲端。在終端機的專案目錄中執行以下命令:
amplify push # press Y when asked to continue
一段時間後,您應看到以下訊息:
✔ All resources are updated in the cloud Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/ Test Your Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/login?response_type=code&client_id=1234567890&redirect_uri=gettingstarted://
-
將 Amplify 身份驗證程式庫新增至專案
在前往程式碼之前,請返回 Android Studio,然後將以下相依項以及之前新增的其他 `amplifyframework` 實作,新增至單元的 `build.gradle` 中,並在提示時按一下 Sync Now (立即同步):
dependencies { ... // Amplify core dependency implementation 'com.amplifyframework:core:1.4.0' implementation 'com.amplifyframework:aws-auth-cognito:1.4.0' }
-
在執行時間設定 Amplify 身份驗證程式庫
返回 Android Studio,開啟 Backend.kt 檔案。在後端類別中,向我們在上一部分 (initialize() 方法中) 新增的 Amplify 初始化程式碼新增一行。
完整的程式碼區塊應如下所示:
// inside Backend class fun initialize(applicationContext: Context) : Backend { try { Amplify.addPlugin(AWSCognitoAuthPlugin()) Amplify.configure(applicationContext) Log.i(TAG, "Initialized Amplify") } catch (e: AmplifyException) { Log.e(TAG, "Could not initialize Amplify", e) } return this }
請勿忘記新增匯入語句,Android Studio 會自動為您執行該操作 (若是 Mac,在程式碼編輯器偵測到的每個錯誤上按一下 Alt + Enter)。
如同上一步操作,為每個缺少的類別定義新增所需的匯入語句 (在紅色字詞上按以下 Alt + Enter)。
若要驗證是否一切如預期,請建置專案。按一下 Build (建置) 功能表,然後選取 Make Project (製作專案),或者在 Mac 上,鍵入 ⌘F9。應不會發生錯誤。
-
在執行時間觸發身份驗證
其餘的程式碼變更會追蹤使用者的狀態 (是否已登入?),並在使用者按一下鎖形圖示時,觸發登入/註冊使用者界面。
a.新增登入和登出方法在後端類別中的任意位置,新增以下四種方法:private fun updateUserData(withSignedInStatus : Boolean) { UserData.setSignedIn(withSignedInStatus) } fun signOut() { Log.i(TAG, "Initiate Signout Sequence") Amplify.Auth.signOut( { Log.i(TAG, "Signed out!") }, { error -> Log.e(TAG, error.toString()) } ) } fun signIn(callingActivity: Activity) { Log.i(TAG, "Initiate Signin Sequence") Amplify.Auth.signInWithWebUI( callingActivity, { result: AuthSignInResult -> Log.i(TAG, result.toString()) }, { error: AuthException -> Log.e(TAG, error.toString()) } ) }
然後為每個缺少的類別定義新增所需的匯入語句 (在紅色字詞上按以下 Alt + Enter)。在多個類別之間進行選擇時,請確保從 Amplify 套件中選擇一個,如下面的螢幕擷取畫面所示。
注意,我們不會從這些方法中更新 UserData.isSignedIn 標誌,這將在下一部分中完成。
b.新增身份驗證中樞接聽程式
為了追蹤身份驗證狀態的變化,我們新增了程式碼以訂閱 Amplify 傳送的身份驗證事件。我們使用 Backend.initialize() 方法來初始化中樞。
收到身份驗證事件後,我們將叫用 updateUserData() 方法。此方法使 UserData 物件保持同步。UserData.isSignedIn 屬性為 LiveData<Boolean>,這意味著當值變更時,將會通知訂閱此屬性的觀察者。我們使用該機制來自動重新整理使用者界面。您可以在 Android 文件中進一步了解有關 LiveData 的資訊。
我們還新增了程式碼,以在應用程式啟動時檢查之前的身份驗證狀態。當應用程式啟動時,其會檢查 Cognito 工作階段是否已存在,並相應地更新 UserData。
在 Backend.initialize() 中,在試用/擷取區塊之後和返回語句之前新增以下程式碼。
// in Backend.initialize() function, after the try/catch block but before the return statement Log.i(TAG, "registering hub event") // listen to auth event Amplify.Hub.subscribe(HubChannel.AUTH) { hubEvent: HubEvent<*> -> when (hubEvent.name) { InitializationStatus.SUCCEEDED.toString() -> { Log.i(TAG, "Amplify successfully initialized") } InitializationStatus.FAILED.toString() -> { Log.i(TAG, "Amplify initialization failed") } else -> { when (AuthChannelEventName.valueOf(hubEvent.name)) { AuthChannelEventName.SIGNED_IN -> { updateUserData(true) Log.i(TAG, "HUB : SIGNED_IN") } AuthChannelEventName.SIGNED_OUT -> { updateUserData(false) Log.i(TAG, "HUB : SIGNED_OUT") } else -> Log.i(TAG, """HUB EVENT:${hubEvent.name}""") } } } } Log.i(TAG, "retrieving session status") // is user already authenticated (from a previous execution) ? Amplify.Auth.fetchAuthSession( { result -> Log.i(TAG, result.toString()) val cognitoAuthSession = result as AWSCognitoAuthSession // update UI this.updateUserData(cognitoAuthSession.isSignedIn) when (cognitoAuthSession.identityId.type) { AuthSessionResult.Type.SUCCESS -> Log.i(TAG, "IdentityId: " + cognitoAuthSession.identityId.value) AuthSessionResult.Type.FAILURE -> Log.i(TAG, "IdentityId not present because: " + cognitoAuthSession.identityId.error.toString()) } }, { error -> Log.i(TAG, error.toString()) } )
若要驗證是否一切如預期,請建置專案。按一下 Build (建置) 功能表,然後選取 Make Project (製作專案),或者在 Mac 上,鍵入 ⌘F9。應不會發生錯誤。
c.更新使用者界面程式碼
程式碼中的最後變更與使用者界面相關,我們在主要活動中新增 FloatingActionButton。
在 res/layout 下,開啟 activity_main.xml 並使用以下項取代現有的 FloatingActionButton:
<com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fabAuth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_baseline_lock" app:fabCustomSize="60dp" app:fabSize="auto" />
在 res/drawable 下新增一個鎖形圖示。在 drawable 上按一下滑鼠右鍵,選取 New (新建),然後選取 Vector Asset (向量資產)。從美工圖案中選擇鎖形圖示,然後輸入 ic_baseline_lock (不帶 _24) 作為名稱,然後從美工圖案中選擇閉合的鎖形圖示。按一下 Next (下一步),然後按一下 Finish (完成)。
對打開的鎖形圖示重複相同的操作。
之後,您應在可繪製目錄中包含以下檔案:
現在,在程式碼中連結新建立的按鈕。在 java/com.example.androidgettingstarted/ 下,開啟 MainActivity.kt 並新增以下程式碼。
// anywhere in the MainActivity class private fun setupAuthButton(userData: UserData) { // register a click listener fabAuth.setOnClickListener { view -> val authButton = view as FloatingActionButton if (userData.isSignedIn.value!!) { authButton.setImageResource(R.drawable.ic_baseline_lock_open) Backend.signOut() } else { authButton.setImageResource(R.drawable.ic_baseline_lock_open) Backend.signIn(this) } } }
仍在 MainActivity 中,在 onCreate() 方法末尾新增以下程式碼:
setupAuthButton(UserData) UserData.isSignedIn.observe(this, Observer<Boolean> { isSignedUp -> // update UI Log.i(TAG, "isSignedIn changed : $isSignedUp") if (isSignedUp) { fabAuth.setImageResource(R.drawable.ic_baseline_lock_open) } else { fabAuth.setImageResource(R.drawable.ic_baseline_lock) } })
上面的程式碼在 Userdata.isSignedIn 值上註冊了一位觀察者。當 isSignedIn 值變更時,將叫用閉合。現在,我們只需變更鎖形圖示:對使用者進行身份驗證時將其打開,而在沒有工作階段時將其閉合。
若要驗證是否一切如預期,請建置專案。按一下 Build (建置) 功能表,然後選取 Make Project (製作專案),或者在 Mac 上,鍵入 ⌘F9。應不會發生錯誤。
d.更新 AndroidManifest.xml 和 MainActivity
最後,我們必須確保在 Cognito 託管的使用者界面所提供的 Web 身份驗證序列末尾,啟動我們的應用程式。我們在資訊清單中新增了一個新的活動。收到 gettingstarted URI 結構描述時將叫用該活動。
在 Android Studio 中的資訊清單下,開啟 AndroidManifest.xml,然後將以下活動新增至應用程式元素。
<activity android:name="com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsRedirectActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="gettingstarted" /> </intent-filter> </activity>
在 java/com.example.androidgettingstarted/ 下,開啟 MainActivity.kt 並在類別的任意位置新增以下程式碼。
// MainActivity.kt // receive the web redirect after authentication override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) Backend.handleWebUISignInResponse(requestCode, resultCode, data) }
在 java/com.example.androidgettingstarted/ 下,開啟 Backend.kt 並在類別的任意位置新增以下程式碼。
// Backend.kt // pass the data from web redirect to Amplify libs fun handleWebUISignInResponse(requestCode: Int, resultCode: Int, data: Intent?) { Log.d(TAG, "received requestCode : $requestCode and resultCode : $resultCode") if (requestCode == AWSCognitoAuthPlugin.WEB_UI_SIGN_IN_ACTIVITY_CODE) { Amplify.Auth.handleWebUISignInResponse(data) } }
e.建置和測試
若要驗證是否一切如預期,請建置並執行專案。按一下工具列中的 Run (執行) 圖示 ▶️,或鍵入 ^ R。應不會發生錯誤。該應用程式即會啟動,螢幕右下角出現一個閉合的鎖形浮動按鈕。
這就是完整的註冊流程。