Condividi tramite


Esercitazione: Aggiungere l'iscrizione in un'app per dispositivi mobili iOS usando l'autenticazione nativa

Questa esercitazione illustra come iscrivere un utente usando il passcode monouso o il nome utente (indirizzo di posta elettronica) e la password e raccoglie gli attributi utente nell'app per dispositivi mobili iOS usando l'autenticazione nativa.

  • Iscrivere un utente usando il passcode monouso o il nome utente (e-mail) e la password.
  • Raccogliere gli attributi utente durante l'iscrizione
  • Gestire gli errori di iscrizione.

Prerequisiti

Iscrivere un utente

Per iscrivere un utente usando il passcode monouso o il nome utente (e-mail) e la password, si acquisisce un messaggio di posta elettronica dall'utente, quindi si invia un messaggio di posta elettronica contenente un passcode monouso all'utente. L'utente immette un passcode monouso di posta elettronica valido per convalidare il proprio nome utente.

Per iscrivere un utente, è necessario:

  1. Creare un'interfaccia utente (IU) per:

    • Acquisire un’e-mail dall'utente. Aggiungere la convalida agli input per assicurarsi che l'utente immetta un indirizzo di posta elettronica valido.
    • Acquisire una password se si effettua l'iscrizione con il nome utente (e-mail) e la password.
    • Acquisire un passcode monouso tramite e-mail dall'utente.
    • Se necessario, acquisire gli attributi utente.
    • Inviare nuovamente il passcode monouso se l'utente non lo riceve.
    • Avviare il flusso di iscrizione.
  2. Nell'app, aggiungere un pulsante, il cui evento select attiva il frammento di codice seguente:

    @IBAction func signUpPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "Email or password not set"
            return
        }
    
        nativeAuth.signUp(username: email, delegate: self)
    }
    
    • Per iscriversi a un utente usando un passcode monouso tramite posta elettronica, viene usato il metodo della signUp(username:delegate) libreria, che risponde in modo asincrono chiamando uno dei metodi sull'oggetto delegato passato, che deve implementare il SignUpStartDelegate protocollo. La riga di codice seguente avvia il processo di iscrizione dell'utente:

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

      signUp(username:delegate) Nel metodo passiamo l'indirizzo di posta elettronica dell'utente dal modulo di invio e dal delegato (una classe che implementa il SignUpStartDelegate protocollo).

    • Per iscriversi a un utente tramite posta elettronica con password, usare i frammenti di codice seguenti:

      @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)
      }
      

      viene usato il metodo della signUp(username:password:delegate) libreria, che risponde in modo asincrono chiamando uno dei metodi sull'oggetto delegato passato, che deve implementare il SignUpStartDelegate protocollo. La riga di codice seguente avvia il processo di iscrizione dell'utente:

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

      signUp(username:password:delegate) Nel metodo viene passato l'indirizzo di posta elettronica dell'utente, la password e il delegato (una classe che implementa il SignUpStartDelegate protocollo).

    • Per implementare il protocollo SignUpStartDelegate come estensione per la nostra classe, usare:

      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)"
          }
      }
      

      La chiamata a signUp(username:password:delegate) o signUp(username:delegate) restituisce una chiamata a o onSignUpCodeRequired()onSignUpStartError() a metodi delegati. onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) viene chiamato per indicare che è stato inviato un codice per verificare l'indirizzo e-mail dell'utente. Oltre ad alcuni dettagli sul dove è stato inviato il codice e sul numero di cifre che contiene, questo metodo delegato ha anche un parametro newState di tipo SignUpCodeRequiredState, che consente di accedere a due nuovi metodi:

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

      Per inviare il codice fornito dall'utente, usare:

      newState.submitCode(code: userSuppliedCode, delegate: self)
      
      • Per implementare il protocollo SignUpVerifyCodeDelegate come estensione per la nostra classe, usare:

        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!"
            }
        }
        

        submitCode(code:delegate) accetta un parametro delegato e occorre implementare i metodi richiesti nel protocollo SignUpVerifyCodeDelegate. Nello scenario più comune viene ricevuta una chiamata a che onSignUpCompleted(newState) indica che l'utente è stato registrato e che il flusso è completo.

Raccogliere gli attributi utente durante l'iscrizione

Se si effettua l'iscrizione a un utente usando un passcode monouso o un nome utente (indirizzo di posta elettronica) e una password, è possibile raccogliere gli attributi utente prima che venga creato l'account di un utente. Il signUp(username:attributes:delegate) metodo accetta attributi come parametro.

  1. Per raccogliere gli attributi utente, usare il frammento di codice seguente:

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

    ignUp(username:password:attributes:delegate) O signUp(username:attributes:delegate) restituisce una chiamata a onSignUpCodeRequired() metodi o onSignUpStartError() delegati oppure in una chiamata a onSignUpAttributesInvalid(attributeNames: [String]) se viene implementata nel delegato.

  2. Per implementare il protocollo SignUpStartDelegate come estensione della classe, usare il frammento di codice seguente:

    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)"
        }
    }
    

    Se gli attributi non sono validi, viene chiamato il metodo onSignUpAttributesInvalid(attributeNames: [String]). In questo caso viene visualizzato l'elenco di attributi non validi per l'utente. In caso contrario viene chiamato onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) per indicare che è stato inviato un codice per verificare l'indirizzo e-mail dell'utente. Oltre ai dettagli, ad esempio il destinatario del codice e il numero di cifre del codice, questo metodo delegato ha un newState parametro di tipo SignUpCodeRequiredState, che consente di accedere a due nuovi metodi:

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

Attributi utente in una o più pagine

Per distribuire gli attributi in una o più pagine, è necessario impostare come obbligatori gli attributi che si intende raccogliere in pagine diverse nella configurazione del tenant di gestione delle identità e degli accessi del cliente.

Si chiama signUp(username:password:delegate) senza passare attributi. Il passaggio successivo consiste nel chiamare newState.submitCode(code: userSuppliedCode, delegate: self) per verificare l'indirizzo di posta elettronica dell'utente.

Si implementa il protocollo SignUpVerifyCodeDelegate come estensione della classe come in precedenza, ma questa volta, oltre ai metodi obbligatori, è necessario implementare il metodo facoltativo onSignUpAttributesRequired(attributes:newState):

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!"
    }
}

Questo metodo delegato ha un parametro newState di tipo SignUpAttributesRequiredState, che consente di accedere a un nuovo metodo:

  • submitAttributes(attributes:delegate)

Per inviare gli attributi forniti dall'utente, usare il frammento di codice seguente:

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

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

Si implementerà anche il protocollo SignUpAttributesRequiredDelegate come estensione della 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!"
    }
}

Quando l'utente non fornisce tutti gli attributi obbligatori o gli attributi non sono validi, vengono chiamati questi metodi delegati:

  • onSignUpAttributesInvalid: indica che uno o più attributi inviati non sono riusciti a convalidare l'input. Questo errore contiene un parametro attributeNames, ovvero un elenco di tutti gli attributi inviati dallo sviluppatore per i quali la convalida dell'input non è riuscita.
  • onSignUpAttributesRequired: indica che il server richiede l'invio di uno o più attributi, prima che sia possibile creare l'account utente. Questo si verifica quando uno o più attributi sono impostati come obbligatori nella configurazione del tenant. Questo risultato contiene i parametri degli attributi, ovvero un elenco di oggetti MSALNativeAuthRequiredAttribute, che descrivono i dettagli relativi agli attributi utente richiesti dall'API.

Entrambi i metodi delegati contengono un riferimento al nuovo stato. Viene usato il newState parametro per chiamare submitAttributes(attributes:delegate) di nuovo con i nuovi attributi.

Gestire gli errori di iscrizione

Durante l'iscrizione non tutte le azioni vengono completate correttamente. Ad esempio, l'utente potrebbe provare a iscriversi con un indirizzo di posta elettronica già in uso oppure inviare un codice non valido.

Nell'implementazione precedente del protocollo SignUpStartDelegate l'errore veniva semplicemente visualizzato durante la gestione della funzione di delegato onSignUpStartError(error).

Per migliorare l'esperienza utente e gestire il tipo di errore specifico, usare il frammento di codice seguente:

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")"
    }
}

Facoltativo: accedere dopo un flusso di iscrizione

Dopo un flusso di iscrizione andato a buon fine, è possibile far accedere l’utente senza avviare un flusso di accesso. Per altre informazioni, vedere l'articolo Esercitazione: Accedere automaticamente all'utente dopo l'iscrizione in un'app iOS.

Passaggio successivo