Tutoriel : réinitialisation de mot de passe en libre-service dans l’application iOS/macOS
S’applique à : iOS (Swift) macOS (Swift)
Ce tutoriel montre comment permettre aux utilisateurs de changer ou de réinitialiser leur mot de passe, sans intervention d’un administrateur ou du support technique.
Dans ce tutoriel, vous allez apprendre à :
- Ajoutez la réinitialisation de mot de passe en libre-service.
- Gérer les erreurs.
Prérequis
Réinitialiser le mot de passe
Pour réinitialiser le mot de passe d’un utilisateur existant, nous devons valider l’adresse e-mail à l’aide d’un mot de passe à usage unique (OTP).
Pour valider l’e-mail, nous appelons la méthode
resetPassword(username:delegate)
à partir de l’instance du Kit de développement logiciel (SDK) à l’aide de l’extrait de code suivant :nativeAuth.resetPassword(username: email, delegate: self)
Pour implémenter le protocole
ResetPasswordStartDelegate
en tant qu’extension de notre classe, utilisez l’extrait de code suivant :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")" } }
L’appel à
resetPassword(username:delegate)
entraîne un appel à la méthode déléguéeonResetPasswordCodeRequired()
ouonResetPasswordStartError()
.Dans le scénario le plus probable, la méthode
onResetPasswordCodeRequired(newState:sentTo:channelTargetType:codeLength)
sera appelée pour indiquer qu’un code a été envoyé pour vérifier l’adresse e-mail de l’utilisateur. Outre les détails de l’emplacement depuis lequel le code a été envoyé et le nombre de chiffres qu’il contient, cette méthode déléguée dispose également d’un paramètrenewState
de typeResetPasswordCodeRequiredState
, ce qui nous donne accès à deux nouvelles méthodes :submitCode(code:delegate)
resendCode(delegate)
Pour soumettre le code que l’utilisateur nous a fourni, utilisez :
newState.submitCode(code: userSuppliedCode, delegate: self)
Pour vérifier le code envoyé, commencez par implémenter le protocole
ResetPasswordVerifyCodeDelegate
en tant qu’extension à votre classe à l’aide de l’extrait de code suivant :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 } }
Dans le scénario le plus courant, nous recevons un appel à
onPasswordRequired(newState)
indiquant que nous pouvons fournir le nouveau mot de passe à l’aide de l’instancenewState
.newState.submitPassword(password: newPassword, delegate: self)
Pour implémenter le protocole
ResetPasswordRequiredDelegate
en tant qu’extension de notre classe, utilisez l’extrait de code suivant :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" } }
Dans le scénario le plus courant, nous recevons un appel à
onResetPasswordCompleted(newState)
indiquant que le flux de réinitialisation de mot de passe est terminé.
Gérer les erreurs
Dans notre implémentation antérieure du protocole ResetPasswordStartDelegate
, nous affichions l’erreur lorsque nous gérions la fonction onResetPasswordStartError(error)
déléguée.
Nous pouvons améliorer l’expérience utilisateur en gérant le type d’erreur spécifique comme suit :
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")"
}
}
Gérer les erreurs avec des états
Certaines erreurs incluent une référence à un nouvel état. Par exemple, si l’utilisateur entre un code de vérification d’e-mail incorrect, le gestionnaire d’erreurs inclut une référence à un ResetPasswordCodeRequiredState
qui peut être utilisé pour envoyer un nouveau code de vérification.
Dans notre implémentation précédente du protocole ResetPasswordVerifyCodeDelegate
, nous n’affichions l’erreur que lorsque nous gérions la fonction onResetPasswordError(error:newState)
déléguée.
Nous pouvons améliorer l’expérience utilisateur en demandant à l’utilisateur d’entrer le code approprié et de le soumettre de nouveau comme suit :
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")"
}
}
Un autre exemple où le gestionnaire d’erreurs inclut une référence à un nouvel état est lorsque l’utilisateur entre un mot de passe non valide. Dans ce cas, le gestionnaire d’erreurs inclut une référence à un ResetPasswordRequiredState
qui peut être utilisé pour envoyer un nouveau mot de passe. Voici un exemple :
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")"
}
}
Se connecter après la réinitialisation du mot de passe
Le kit de développement logiciel (SDK) permet aux développeurs de connecter un utilisateur après avoir réinitialisé leur mot de passe, sans avoir à fournir le nom d’utilisateur ou à vérifier l’adresse e-mail via un code secret à usage unique.
Pour connecter un utilisateur après une réinitialisation de mot de passe réussie, utilisez la méthode signIn(delegate)
à partir du nouvel état SignInAfterResetPasswordState
retourné dans la fonction onResetPasswordCompleted(newState)
:
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)
}
}
La méthode signIn(delegate)
accepte un paramètre délégué et nous devons implémenter les méthodes requises dans le protocole SignInAfterResetPasswordDelegate
.
Dans le scénario le plus courant, nous recevons un appel à onSignInCompleted(result)
indiquant que l’utilisateur s’est connecté. Le résultat peut être utilisé pour récupérer 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)
}
}
La méthode getAccessToken(delegate)
accepte un paramètre délégué et nous devons implémenter les méthodes requises dans le protocole CredentialsDelegate
.
Dans le scénario le plus courant, nous recevons un appel à onAccessTokenRetrieveCompleted(result)
indiquant que l’utilisateur a obtenu un access token
.
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)"
}
}