共用方式為


教學課程:使用原生驗證在 Android 應用程式中新增登入

本教學課程將示範如何使用原生驗證,在 Android 行動應用程式中利用電子郵件一次性密碼或使用者名稱及密碼登入與登出使用者。

在本教學課程中,您會了解如何:

  • 使用電子郵件一次性密碼或使用者名稱 (電子郵件) 及密碼登入使用者。
  • 登出使用者。
  • 處理登入錯誤

必要條件

登入使用者

若要以一次性密碼登入使用者,請收集電子郵件,並向使用者傳送包含一次性密碼的電子郵件,以便其驗證其電子郵件。 使用者輸入有效的一次性密碼後,應用程式便會將其登入。

若要以使用者名稱 (電子郵件) 及密碼登入使用者,請收集使用者的電子郵件與密碼。 若使用者名稱及密碼有效,應用程式便會登入使用者。

若要登入使用者,您必須:

  1. 建立使用者介面 (UI) 以:

    • 收集使用者的電子郵件。 在輸入新增驗證,確保使用者輸入有效的電子郵件地址。
    • 若要以使用者名稱 (電子郵件) 及密碼登入,請收集密碼。
    • 若要以電子郵件一次性密碼登入,請收集使用者的電子郵件一次性密碼。
    • 若要以電子郵件一次性密碼登入,請重新傳送一次性密碼 (建議)。
  2. 在 UI 中新增其選取事件會觸發登入的按鈕,如下列程式碼片段所示:

     CoroutineScope(Dispatchers.Main).launch {
         val actionResult = authClient.signIn(
             username = emailAddress
             //password = password, Pass 'password' param if you sign in with username (email) and password
         )
         if (actionResult is SignInResult.CodeRequired) {
             val nextState = actionResult.nextState
             val submitCodeActionResult = nextState.submitCode(
                 code = code
             )
             if (submitCodeActionResult is SignInResult.Complete){
                 // Handle sign in success
                 val accountState = submitCodeActionResult.resultValue
                 val accessTokenResult = accountState.getAccessToken()
                 if (accessTokenResult is GetAccessTokenResult.Complete) {
                     val accessToken = accessTokenResult.resultValue.accessToken
                     val idToken = accountState.getIdToken()
                 }
             }
         }
     }
    

    若使用者不須提交密碼,例如使用者以電子郵件與密碼登入的狀況,請使用下列程式碼片段:

        CoroutineScope(Dispatchers.Main).launch {
            val actionResult = authClient.signIn(
                username = emailAddress,
                password = password
            )
            if (actionResult is SignInResult.Complete) -> {
                // Handle sign in success
                val accountState = actionResult.resultValue
                val accessTokenResult = accountState.getAccessToken()
                if (accessTokenResult is GetAccessTokenResult.Complete) {
                        val accessToken = accessTokenResult.resultValue.accessToken
                        val idToken = accountState.getIdToken()
                    }
            }
        }
    
    • 若要起動登入流程,請使用 SDK 的 signIn(username)signIn(username, password) 方法。
    • 方法的參數 username 即為您收集的使用者電子郵件地址。
    • 若以使用者名稱 (電子郵件) 及密碼登入,則方法的參數 password 將為您收集的使用者密碼。
    • 在最常見的案例中,signIn(username)signIn(username, password) 會傳回結果 SignInResult.CodeRequired,表示 SDK 預期應用程式會提交傳送給使用者電子郵件地址的電子郵件一次性密碼。
    • SignInResult.CodeRequired 物件包含新狀態的參考,並可以透過 actionResult.nextState 來擷取。
    • 透過新狀態,可使用下列兩種新方法:
      • submitCode() 會提交應用程式收集的使用者電子郵件一次性密碼。
      • 若使用者未收到密碼,resendCode() 會重新傳送電子郵件一次性密碼。

處理登入錯誤

在登入過程中,並非所有動作都會成功。 例如,使用者可能會嘗試使用不存在的電子郵件地址來登入,或提交無效的密碼。

處理登入啟動錯誤

若要處理 signIn(username)signIn(username, password) 方法中的錯誤,請使用下列程式碼片段:

val actionResult = authClient.sign(
    username = emailAddress
    //password = password, Pass 'password' param if you sign in with username (email) and password
)
if (actionResult is SignInResult.CodeRequired) {
    // Next step: submit code
} else if (actionResult is SignInError) {
    // Handle sign in errors
    when {
         actionResult.isUserNotFound() -> {
             // Handle "user not found" error
         }
         actionResult.isAuthNotSupported() -> {
         // Handle "authentication type not support" error
         }
         actionResult.isInvalidCredentials() -> {
             // Handle specific errors
         }
         else -> {
             // Handle other errors
         }
     }
}
  • SignInError 表示 signIn() 傳回的動作結果失敗,因此動作結果並未包含新狀態的參考。
  • 若為 actionResult is SignUpError,Android SDK 會提供可進一步分析特定錯誤的公用程式方法:
    • 方法 isUserNotFound() 會檢查使用者是否使用不存在的使用者名稱 (電子郵件位址) 登入。
    • 方法 isBrowserRequired() 會檢查是否需要瀏覽器 (Web 後援) 來完成驗證流程。 若原生驗證不足以完成驗證流程,便會發生這種情況。 例如,系統管理員將電子郵件和密碼設定為驗證方法,但應用程式無法以查問類型傳送密碼,或不支援該類型。 請使用在 Android 應用程式中支援 Web 後援中的步驟來處理此類狀況。
    • 方法 isAuthNotSupported() 會檢查應用程式是否傳送 Microsoft Entra 不支援的查問類型,即 oobpassword 之外的查問類型值。 深入瞭解查問類型
    • 針對以使用者名稱 (電子郵件) 及密碼登入,方法 isInvalidCredentials() 會檢查使用者名稱與密碼的組合是否不正確。

處理提交密碼錯誤

若要處理 submitCode() 方法中的錯誤,請使用下列程式碼片段:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInResult.Complete) {
    // Sign in flow complete, handle success state.
} else if (submitCodeActionResult is SubmitCodeError && submitCodeActionResult.isInvalidCode()) {
    // Handle "invalid code" error
}
  • SubmitCodeError 錯誤表示 submitCode() 傳回的動作結果失敗,因此動作結果並未包含新狀態的參考。
  • isInvalidCode() 會檢查特定錯誤。 在此案例中,必須使用先前的狀態參考來重新執行動作。

若要擷取新的電子郵件一次性密碼,請使用下列程式碼片段:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInError && submitCodeActionResult.isInvalidCode) {
    // Inform the user that the submitted code was incorrect or invalid, then ask them to input a new email one-time passcode
    val newCode = retrieveNewCode()
    nextState.submitCode(
        code = newCode
    )
}

您已完成在應用程式上成功登入使用者所需的所有步驟。 建置並執行您的應用程式。 若一切順利,您應能提供電子郵件、透過電子郵件接收密碼,以及使用該密碼成功登入使用者。

讀取識別碼權杖宣告

應用程式取得識別碼權杖後,您就可以擷取與目前帳戶相關聯的宣告。 若要執行此動作,請使用下列程式碼片段。

val preferredUsername = accountState.getClaims()?.get("preferred_username")
val city = accountState.getClaims()?.get("City")
val givenName = accountState.getClaims()?.get("given_name")
//custom attribute
val loyaltyNumber = accountState.getClaims()?.get("loyaltyNumber")

用於存取宣告值的索引鍵,即為您將使用者屬性新增為權杖宣告時所指定的名稱。

若要瞭解如何將內建和自訂的使用者屬性新增至權杖宣告,請參閱將使用者屬性新增至權杖宣告一文。

登出使用者

若要登出使用者,您必須移除目前儲存於快取中的帳戶。

  1. 建立包含下列項目的自訂使用者介面 (UI):

    • 使用者可選取以傳送登出要求的登出按鈕。
  2. 若要登出使用者,請使用下列程式碼:

    private fun performSignOut(accountState: AccountState) {
         CoroutineScope(Dispatchers.Main).launch {
            val accountResult = authClient.getCurrentAccount()
             if (accountResult is GetAccountResult.AccountFound) {
                 val signOutResult = accountResult.resultValue.signOut()
                 if (signOutResult is SignOutResult.Complete) {
                     // Show sign out successful UI
                 }
             }
         }
     }
    

處理登出錯誤

登出時應不會發生錯誤。 若發生任何錯誤,請使用下列程式碼片段檢查錯誤結果:

val actionResult = accountResult.signOut()
if (actionResult is SignOutResult.Complete) {
    // Show sign out successful UI
} else {
    // Handle errors
}

請確定其中包含 import 陳述式。 Android Studio 應該會自動包含 import 陳述式。

您已完成在應用程式上成功登出使用者所需的所有步驟。 建置並執行您的應用程式。 若一切順利,您應能選取 [登出] 按鈕以成功登出。

設定自定義宣告提供者

如果您想要將來自外部系統的宣告新增至發行至應用程式的令牌,請使用 自定義宣告提供者。 自定義宣告提供者是由自定義驗證延伸模組所組成,可呼叫外部 REST API 從外部系統擷取宣告。

請遵循設定自定義宣告提供者中的步驟,將外部系統的宣告新增至您的安全性令牌。