Partager via


Tutoriel : ajouter une inscription à une application iOS/macOS à l’aide de l’authentification native

S’applique à : Cercle vert avec un symbole de coche blanche. iOS (Swift) Cercle vert avec un symbole de coche blanche. macOS (Swift)

Ce tutoriel montre comment inscrire un utilisateur à l’aide d’un code secret à usage unique envoyé par e-mail ou d’un nom d’utilisateur (e-mail) et d’un mot de passe, et à collecter les attributs utilisateur dans votre application iOS/macOS à l’aide de l’authentification native.

  • Inscrivez un utilisateur à l’aide d’un code secret à usage unique envoyé par e-mail ou d’un nom d’utilisateur (e-mail) et d’un mot de passe.
  • Collecter les attributs utilisateur lors de l’inscription.
  • Gérer les erreurs d’inscription.

Prérequis

Inscrire un utilisateur

Pour inscrire un utilisateur à l’aide d’un code secret à usage unique envoyé par e-mail ou d’un nom d’utilisateur (e-mail) et d’un mot de passe, collectez l’adresse e-mail de l’utilisateur, puis envoyez-lui un e-mail contenant un code secret à usage unique. L’utilisateur entre un code secret à usage unique valide pour valider son nom d’utilisateur.

Pour inscrire un utilisateur, vous devez :

  1. Créer une interface utilisateur pour :

    • Collecter une adresse e-mail de l’utilisateur. Ajouter une validation à vos entrées pour vérifier que l’utilisateur entre une adresse e-mail valide.
    • Collecter un mot de passe si vous vous inscrivez avec un nom d’utilisateur (e-mail) et un mot de passe.
    • Collecter auprès de l’utilisateur un code secret à usage unique envoyé par e-mail.
    • Collecter les attributs utilisateur, si besoin.
    • Renvoyez le code secret à usage unique si l’utilisateur ne l’a pas reçu.
    • Démarrer le flux d’inscription.
  2. Dans votre application, ajoutez un bouton dont l’événement de sélection déclenche l’extrait de code suivant :

    @IBAction func signUpPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "Email or password not set"
            return
        }
    
        nativeAuth.signUp(username: email, delegate: self)
    }
    
    • Pour inscrire un utilisateur avec un code secret à usage unique envoyé par e-mail, nous utilisons la méthode signUp(username:delegate) de la bibliothèque, qui répond de manière asynchrone en appelant l’une des méthodes sur l’objet délégué transmis, lequel doit implémenter le protocole SignUpStartDelegate. La ligne de code suivante lance le processus d’inscription de l’utilisateur :

      nativeAuth.signUp(username: email, delegate: self)
      

      Dans la méthode signUp(username:delegate), nous transmettons l’adresse e-mail de l’utilisateur à partir du formulaire de soumission et le délégué (classe qui implémente le protocole SignUpStartDelegate).

    • Pour inscrire un utilisateur avec une adresse e-mail et un mot de passe, utilisez les extraits de code suivants :

      @IBAction func signUpPressed(_: Any) {
          guard let email = emailTextField.text, let password = passwordTextField.text else {
              resultTextView.text = "Email or password not set"
              return
          }
      
          nativeAuth.signUp(username: email,password: password,delegate: self)
      }
      

      Nous utilisons la méthode signUp(username:password:delegate) de la bibliothèque, qui répond de manière asynchrone en appelant l’une des méthodes sur l’objet délégué transmis, lequel doit implémenter le protocole SignUpStartDelegate. La ligne de code suivante lance le processus d’inscription de l’utilisateur :

      nativeAuth.signUp(username: email, password: password, delegate: self)
      

      Dans la méthode signUp(username:password:delegate), nous transmettons l’adresse e-mail de l’utilisateur, son mot de passe et le délégué (classe qui implémente le protocole SignUpStartDelegate).

    • Pour implémenter le protocole SignUpStartDelegate en tant qu’extension de notre classe, utilisez :

      extension ViewController: SignUpStartDelegate {
          func onSignUpStartError(error: MSAL.SignUpStartError) {
              resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
          }
      
          func onSignUpCodeRequired(
              newState: MSAL.SignUpCodeRequiredState,
              sentTo: String,
              channelTargetType: MSAL.MSALNativeAuthChannelType,
              codeLength: Int
          ) {
              resultTextView.text = "Verification code sent to \(sentTo)"
          }
      }
      

      L’appel à signUp(username:password:delegate) ou signUp(username:delegate) entraîne un appel aux méthodes déléguées onSignUpCodeRequired() ou onSignUpStartError(). La méthode onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) est 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ètre newState de type SignUpCodeRequiredState, 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 implémenter le protocole SignUpVerifyCodeDelegate en tant qu’extension de notre classe, utilisez :

        extension ViewController: SignUpVerifyCodeDelegate {
            func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
                resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
            }
        
            func onSignUpCompleted(newState: SignInAfterSignUpState) {
                resultTextView.text = "Signed up successfully!"
            }
        }
        

        La méthode submitCode(code:delegate) accepte un paramètre délégué et nous devons implémenter les méthodes requises dans le protocole SignUpVerifyCodeDelegate. Dans le scénario le plus courant, nous recevons un appel à onSignUpCompleted(newState) indiquant que l’utilisateur a été inscrit et que le flux est terminé.

Collecter les attributs utilisateur lors de l’inscription

Que vous inscriviez un utilisateur à l’aide d’un code secret à usage unique envoyé par e-mail ou à l’aide d’un nom d’utilisateur (e-mail) et d’un mot de passe, vous pouvez collecter les attributs utilisateur avant la création du compte de l’utilisateur. La méthode signUp(username:attributes:delegate) accepte les attributs en tant que paramètre.

  1. Pour collecter les attributs utilisateur, utilisez l’extrait de code suivant :

    let attributes = [
        "country": "United States",
        "city": "Redmond"
    ]
    
    nativeAuth.signUp(username: email, attributes: attributes, delegate: self)
    

    signUp(username:attributes:delegate) ou ignUp(username:password:attributes:delegate) entraîne un appel aux méthodes déléguées onSignUpCodeRequired() ou onSignUpStartError(), ou un appel à onSignUpAttributesInvalid(attributeNames: [String]) s’il est implémenté dans le délégué.

  2. Pour implémenter le protocole SignUpStartDelegate en tant qu’extension de notre classe, utilisez l’extrait de code suivant :

    extension ViewController: SignUpStartDelegate {
        func onSignUpStartError(error: MSAL.SignUpStartError) {
            resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
        }
    
        func onSignUpCodeRequired(
            newState: MSAL.SignUpCodeRequiredState,
            sentTo: String,
            channelTargetType: MSAL.MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    
        func onSignUpAttributesInvalid(attributeNames: [String]) {
           resultTextView.text = "Invalid attributes  \(attributeNames)"
        }
    }
    

    Si les attributs ne sont pas valides, la méthode onSignUpAttributesInvalid(attributeNames: [String]) est appelée. Dans ce cas, nous affichons la liste des attributs non valides pour l’utilisateur. Sinon, la méthode onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) est appelée pour indiquer qu’un code a été envoyé pour vérifier l’adresse e-mail de l’utilisateur. En plus des détails tels que le destinataire du code et le nombre de chiffres du code, cette méthode déléguée dispose d’un paramètre newState de type SignUpCodeRequiredState, qui nous donne accès à deux nouvelles méthodes :

    • submitCode(code:delegate)
    • resendCode(delegate)

Attributs utilisateur sur une ou plusieurs pages

Pour répartir les attributs sur une ou plusieurs pages, nous devons définir les attributs que nous avons l’intention de collecter sur différentes pages comme obligatoires dans la configuration du client d’identité et d’accès (CIAM).

Nous appelons signUp(username:password:delegate) sans passer d’attributs. L’étape suivante consiste à appeler newState.submitCode(code: userSuppliedCode, delegate: self) pour vérifier l’e-mail de l’utilisateur.

Nous implémentons le protocole SignUpVerifyCodeDelegate comme extension à notre classe comme précédemment, mais cette fois nous devons implémenter la méthode facultative onSignUpAttributesRequired(attributes:newState) en plus des méthodes requises :

extension ViewController: SignUpVerifyCodeDelegate {
    func onSignUpAttributesRequired(newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
        resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Cette méthode de délégué a un paramètre newState de type SignUpAttributesRequiredState, qui nous donne accès à une nouvelle méthode :

  • submitAttributes(attributes:delegate)

Pour envoyer les attributs que l’utilisateur nous a fournis, utilisez l’extrait de code suivant :

let attributes = [
    "country": "United States",
    "city": "Redmond"
]

newState.submitAttributes(attributes: attributes, delegate: self)

Nous allons également implémenter le protocole SignUpAttributesRequiredDelegate en tant qu’extension de notre classe :

extension ViewController: SignUpAttributesRequiredDelegate {
    func onSignUpAttributesRequiredError(error: AttributesRequiredError) {
        resultTextView.text = "Error submitting attributes: \(error.errorDescription ?? "no description")"
    }

    func onSignUpAttributesRequired(attributes: [MSALNativeAuthRequiredAttribute], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpAttributesInvalid(attributeNames: [String], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes invalid"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Lorsque l’utilisateur ne fournit pas tous les attributs requis ou que les attributs ne sont pas valides, ces méthodes déléguées sont appelées :

  • onSignUpAttributesInvalid : indique qu’un ou plusieurs attributs envoyés ont échoué à la validation d’entrée. Cette erreur contient un paramètre attributeNames, qui est une liste de tous les attributs envoyés par le développeur qui a échoué la validation d’entrée.
  • onSignUpAttributesRequired : indique que le serveur nécessite l’envoi d’un ou plusieurs attributs avant que le compte d’utilisateur puisse être créé. Cela se produit quand un ou plusieurs attributs sont définis comme obligatoires dans la configuration du locataire. Ce résultat contient le paramètre attributs, une liste d’objets MSALNativeAuthRequiredAttribute, qui décrit les détails sur les attributs utilisateur requis par l’API.

Les deux méthodes déléguées contiennent une nouvelle référence d’état. Nous utilisons le paramètre newState pour appeler une nouvelle fois submitAttributes(attributes:delegate) avec les nouveaux attributs.

Gérer les erreurs d’inscription

Lors de l’inscription, certaines actions peuvent échouer. Par exemple, l’utilisateur peut essayer de s’inscrire avec une adresse e-mail déjà utilisée ou envoyer un code non valide.

Dans notre implémentation antérieure du protocole SignUpStartDelegate, nous n’affichions l’erreur que lorsque nous gérions la fonction onSignUpStartError(error) déléguée.

Pour améliorer l’expérience utilisateur en gérant le type d’erreur particulier, utilisez l’extrait de code suivant :

func onSignUpStartError(error: MSAL.SignUpStartError) {
    if error.isUserAlreadyExists {
        resultTextView.text = "Unable to sign up: User already exists"
    } else if error.isInvalidPassword {
        resultTextView.text = "Unable to sign up: The password is invalid"
    } else if error.isInvalidUsername {
        resultTextView.text = "Unable to sign up: The username is invalid"
    } else {
        resultTextView.text = "Unexpected error signing up: \(error.errorDescription ?? "no description")"
    }
}

Facultatif : Se connecter après un flux d’inscription

Après un flux d’inscription réussi, vous pouvez connecter un utilisateur sans lancer de flux de connexion. Pour plus d’informations, consultez l’article Tutoriel : connecter l’utilisateur automatiquement après son inscription dans une application iOS/macOS.

Étape suivante