教學課程:使用原生驗證在Android應用程式中新增登入
適用於:白色圓圈內有灰色 X 符號 企業租戶
外部租戶(深入了解)
本教學課程示範如何使用原生驗證,在 Android 行動應用程式中使用電子郵件單次密碼或使用者名稱和密碼來登入和註銷使用者。
在本教學課程中,您將瞭解如何:
- 使用電子郵件一次性密碼或使用者名稱(電子郵件)和密碼登入使用者。
- 註銷使用者。
- 處理登入錯誤
先決條件
- 完成 教學課程:準備Android應用程式以進行原生驗證。 本教學課程說明如何準備Android專案或應用程式以進行原生驗證。
登入使用者
若要使用單次密碼登入使用者,請收集電子郵件,並傳送包含一次性密碼的電子郵件,讓使用者驗證其電子郵件。 當使用者輸入有效的單次密碼時,應用程式會將其登入。
若要使用使用者名稱(電子郵件)和密碼登入使用者,請從使用者收集電子郵件和密碼。 如果使用者名稱和密碼有效,應用程式會登入使用者。
若要登入使用者,您需要:
建立使用者介面 (UI) 以:
- 從使用者收集電子郵件。 將驗證新增至您的輸入,以確保使用者輸入有效的電子郵件位址。
- 如果您使用使用者名稱(電子郵件)和密碼登入,請收集密碼。
- 如果您使用電子郵件一次性密碼登入,請從使用者收集電子郵件一次性密碼。
- 如果您使用電子郵件一次性密碼登入,建議您重新傳送一次性密碼。
在您的UI中,新增按鈕,其 select 事件會啟動登入,如下列代碼段所示:
CoroutineScope(Dispatchers.Main).launch { val parameters = NativeAuthSignInParameters(username = email) // Assign 'password' param if you sign in with username (email) and password // parameters.password = password val actionResult: SignInResult = authClient.signIn(parameters) 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 getAccessTokenParameters = NativeAuthGetAccessTokenParameters() val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters) if (accessTokenResult is GetAccessTokenResult.Complete) { val accessToken = accessTokenResult.resultValue.accessToken val idToken = accountState.getIdToken() } } } }
如果使用者不需要提交密碼,例如使用者以電子郵件和密碼登入的位置,請使用下列代碼段:
CoroutineScope(Dispatchers.Main).launch { val parameters = NativeAuthSignInParameters(username = email) parameters.password = password val actionResult: SignInResult = authClient.signIn(parameters) if (actionResult is SignInResult.Complete) -> { // Handle sign in success val accountState = actionResult.resultValue val getAccessTokenParameters = NativeAuthGetAccessTokenParameters() val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters) if (accessTokenResult is GetAccessTokenResult.Complete) { val accessToken = accessTokenResult.resultValue.accessToken val idToken = accountState.getIdToken() } } }
- 若要啟動登入流程,請使用 SDK 的
signIn(parameters)
方法。 -
NativeAuthSignInParameters
類別的實例,包含您從使用者收集的電子郵件位址username
。 - 如果登入方法是使用者名稱(電子郵件)和密碼,則方法的參數
password
是您從使用者收集的密碼。 - 在最常見的案例中,
signIn(parameters)
會傳回結果,SignInResult.CodeRequired
,這表示 SDK 預期應用程式會提交傳送給使用者電子郵件地址的電子郵件一次性密碼。 -
SignInResult.CodeRequired
物件包含新的狀態參考,我們可以透過actionResult.nextState
來擷取。 - 新的狀態可讓我們存取兩個新的方法:
-
submitCode()
提交應用程式向使用者收集的電子郵件一次性密碼。 -
resendCode()
如果使用者未收到代碼,則重新傳送電子郵件一次性密碼。
-
- 若要啟動登入流程,請使用 SDK 的
處理登入錯誤
登入期間,並非所有動作都成功。 例如,使用者可能會嘗試使用不存在的電子郵件位址登入,或提交無效的程序代碼。
處理登入啟動錯誤
若要處理 signIn(parameters)
方法中的錯誤,請使用下列代碼段:
val parameters = NativeAuthSignInParameters(username = email)
// Assign 'password' param if you sign in with username (email) and password
// parameters.password = password
val actionResult: SignInResult = authClient.signIn(parameters)
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(parameters)
傳回的動作結果失敗,因此動作結果不包含新狀態的參考。 - 如果
actionResult is SignUpError
,Android SDK 會提供公用程式方法,讓您進一步分析特定錯誤:- 方法
isUserNotFound()
會檢查使用者是否使用不存在的使用者名稱(電子郵件位址)登入。 - 方法
isBrowserRequired()
檢查是否需要瀏覽器(網頁備援),以完成驗證流程。 當原生驗證不足以完成驗證流程時,就會發生此案例。 例如,系統管理員將電子郵件和密碼設定為驗證方法,但應用程式無法將 密碼 傳送作為挑戰類型,或根本不支援該類型。 使用 Android 應用程式中 支援 Web 後援 的步驟來處理發生時的情境。 - 方法
isAuthNotSupported()
會檢查應用程式是否傳送 Microsoft Entra 不支援的挑戰類型,即除了 oob 和 密碼以外的挑戰類型值。 深入瞭解 挑戰類型。 - 針對使用者名稱(電子郵件)和密碼登入,方法
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
)
}
您已完成在應用程式上成功登入使用者所需的所有步驟。 建置並執行您的應用程式。 如果一切順利,您應該能夠提供電子郵件、接收電子郵件上的代碼,以及使用該代碼成功登入使用者。
讀取標識碼令牌訊息
一旦您的應用程式取得 ID 令牌,就可以取得與目前帳戶相關聯的宣告。 若要這樣做,請使用下列代碼段。
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")
您用來存取宣告值的鍵,就是您在將使用者屬性新增為令牌宣告時所指定的名稱。
若要瞭解如何將內建和自定義屬性新增作為令牌宣告,請參閱文章《將使用者屬性新增至令牌宣告》。
註銷使用者
若要註銷使用者,您必須移除目前儲存在快取中的帳戶。
建立自訂使用者介面 (UI),其中包含:
- 用戶選取的按鈕,用來傳送註銷要求。
若要註銷使用者,請使用下列程式代碼:
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 應該會自動添加導入聲明。
您已完成在應用程式上成功註銷使用者所需的所有步驟。 建置並執行您的應用程式。 如果一切順利,您應該能夠選取 [註銷] 按鈕以成功註銷。
設定自定義宣告提供者
如果您要將來自外部系統的宣告添加至發行給應用程式的權杖,請使用 自訂宣告提供者。 自定義宣告提供者是由自定義驗證延伸模組所組成,可呼叫外部 REST API 從外部系統擷取宣告。
請遵循 設定自定義宣告提供者 中的步驟,將外部系統的宣告新增至安全性令牌。