Samouczek: samoobsługowe resetowanie hasła w aplikacji systemu iOS/macOS
Dotyczy: iOS (Swift) macOS (Swift)
W tym samouczku pokazano, jak zapewnić użytkownikom możliwość zmiany lub zresetowania hasła bez udziału administratora ani działu pomocy technicznej.
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Dodaj samoobsługowe resetowanie hasła.
- Obsługa błędów.
Wymagania wstępne
Resetowanie hasła
Aby zresetować hasło istniejącego użytkownika, musimy zweryfikować adres e-mail przy użyciu jednorazowego kodu dostępu (OTP).
Aby zweryfikować wiadomość e-mail, wywołujemy metodę
resetPassword(username:delegate)
z wystąpienia zestawu SDK przy użyciu następującego fragmentu kodu:nativeAuth.resetPassword(username: email, delegate: self)
Aby zaimplementować
ResetPasswordStartDelegate
protokół jako rozszerzenie klasy, użyj następującego fragmentu kodu:extension ViewController: ResetPasswordStartDelegate { func onResetPasswordCodeRequired( newState: MSAL.ResetPasswordCodeRequiredState, sentTo: String, channelTargetType: MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } }
Wywołanie metody powoduje
resetPassword(username:delegate)
wywołanieonResetPasswordCodeRequired()
metody lubonResetPasswordStartError()
delegowania.W najbardziej typowym scenariuszu
onResetPasswordCodeRequired(newState:sentTo:channelTargetType:codeLength)
zostanie wywołany, aby wskazać, że kod został wysłany w celu zweryfikowania adresu e-mail użytkownika. Wraz ze szczegółowymi informacjami o tym, gdzie został wysłany kod i ile cyfr zawiera, ta metoda delegata manewState
również parametr typuResetPasswordCodeRequiredState
, który daje nam dostęp do dwóch nowych metod:submitCode(code:delegate)
resendCode(delegate)
Aby przesłać kod dostarczony przez użytkownika, użyj:
newState.submitCode(code: userSuppliedCode, delegate: self)
Aby sprawdzić przesłany kod, zacznij od zaimplementowania
ResetPasswordVerifyCodeDelegate
protokołu jako rozszerzenia do klasy przy użyciu następującego fragmentu kodu:extension ViewController: ResetPasswordVerifyCodeDelegate { func onResetPasswordVerifyCodeError( error: MSAL.VerifyCodeError, newState: MSAL.ResetPasswordCodeRequiredState? ) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } func onPasswordRequired(newState: MSAL.ResetPasswordRequiredState) { // use newState instance to submit the new password } }
W najbardziej typowym scenariuszu otrzymujemy wywołanie
onPasswordRequired(newState)
wskazujące, że możemy podać nowe hasło przy użyciunewState
wystąpienia.newState.submitPassword(password: newPassword, delegate: self)
Aby zaimplementować
ResetPasswordRequiredDelegate
protokół jako rozszerzenie klasy, użyj następującego fragmentu kodu:extension ViewController: ResetPasswordRequiredDelegate { func onResetPasswordRequiredError( error: MSAL.PasswordRequiredError, newState: MSAL.ResetPasswordRequiredState? ) { resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")" } func onResetPasswordCompleted(newState: SignInAfterResetPasswordState) { resultTextView.text = "Password reset completed" } }
W najbardziej typowym scenariuszu otrzymujemy wywołanie
onResetPasswordCompleted(newState)
wskazujące, że przepływ resetowania hasła został ukończony.
Obsługa błędów
We wcześniejszej implementacji ResetPasswordStartDelegate
protokołu wyświetliliśmy błąd, gdy obsłużyliśmy funkcję delegata onResetPasswordStartError(error)
.
Możemy ulepszyć środowisko użytkownika, obsługując określony typ błędu w następujący sposób:
func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) {
if error.isInvalidUsername {
resultTextView.text = "Invalid username"
} else if error.isUserNotFound {
resultTextView.text = "User not found"
} else if error.isUserDoesNotHavePassword {
resultTextView.text = "User is not registered with a password"
} else {
resultTextView.text = "Error during reset password flow in: \(error.errorDescription ?? "no description")"
}
}
Obsługa błędów ze stanami
Niektóre błędy obejmują odwołanie do nowego stanu. Jeśli na przykład użytkownik wprowadzi nieprawidłowy kod weryfikacyjny wiadomości e-mail, program obsługi błędów zawiera odwołanie do elementu ResetPasswordCodeRequiredState
, którego można użyć do przesłania nowego kodu weryfikacyjnego.
W poprzedniej implementacji ResetPasswordVerifyCodeDelegate
protokołu po prostu wyświetliliśmy błąd podczas obsługi funkcji delegata onResetPasswordError(error:newState)
.
Możemy ulepszyć środowisko użytkownika, prosząc użytkownika o wprowadzenie poprawnego kodu i ponowne przesłanie go w następujący sposób:
func onResetPasswordVerifyCodeError(
error: MSAL.VerifyCodeError,
newState: MSAL.ResetPasswordCodeRequiredState?
) {
if error.isInvalidCode {
// Inform the user that the submitted code was incorrect and ask for a new code to be supplied.
// Request a new code calling `newState.resendCode(delegate)`
let userSuppliedCode = retrieveNewCode(newState)
newState?.submitCode(code: userSuppliedCode, delegate: self)
} else {
resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
}
}
Innym przykładem, w którym program obsługi błędów zawiera odwołanie do nowego stanu, jest wprowadzenie przez użytkownika nieprawidłowego hasła. W takim przypadku program obsługi błędów zawiera odwołanie do elementu ResetPasswordRequiredState
, którego można użyć do przesłania nowego hasła. Oto przykład:
func onResetPasswordRequiredError(
error: MSAL.PasswordRequiredError,
newState: MSAL.ResetPasswordRequiredState?
) {
if error.isInvalidPassword {
// Inform the user that the submitted password was invalid and ask for a new password to be supplied.
let newPassword = retrieveNewPassword()
newState?.submitPassword(password: newPassword, delegate: self)
} else {
resultTextView.text = "Error submitting password: \(error.errorDescription ?? "no description")"
}
}
Zaloguj się po zresetowaniu hasła
Zestaw SDK zapewnia deweloperom możliwość logowania użytkownika po zresetowaniu hasła bez konieczności podawania nazwy użytkownika lub weryfikowania adresu e-mail za pomocą jednorazowego kodu dostępu.
Aby zalogować użytkownika po pomyślnym zresetowaniu hasła, użyj signIn(delegate)
metody z nowego stanu SignInAfterResetPasswordState
zwróconego onResetPasswordCompleted(newState)
w funkcji:
extension ViewController: ResetPasswordRequiredDelegate {
func onResetPasswordRequiredError(
error: MSAL.PasswordRequiredError,
newState: MSAL.ResetPasswordRequiredState?
) {
resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")"
}
func onResetPasswordCompleted() {
resultTextView.text = "Password reset completed"
newState.signIn(delegate: self)
}
}
Element signIn(delegate)
akceptuje parametr delegata i musimy zaimplementować wymagane metody w protokole SignInAfterResetPasswordDelegate
.
W najbardziej typowym scenariuszu otrzymujemy wywołanie onSignInCompleted(result)
wskazujące, że użytkownik się zalogował. Wynik może służyć do pobrania .access token
extension ViewController: SignInAfterSignUpDelegate {
func onSignInAfterSignUpError(error: SignInAfterSignUpError) {
resultTextView.text = "Error signing in after password reset"
}
func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
// User successfully signed in
result.getAccessToken(delegate: self)
}
}
Element getAccessToken(delegate)
akceptuje parametr delegata i musimy zaimplementować wymagane metody w protokole CredentialsDelegate
.
W najbardziej typowym scenariuszu otrzymujemy wywołanie onAccessTokenRetrieveCompleted(result)
wskazujące, że użytkownik uzyskał access token
element .
extension ViewController: CredentialsDelegate {
func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) {
resultTextView.text = "Error retrieving access token"
}
func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) {
resultTextView.text = "Signed in. Access Token: \(result.accessToken)"
}
}