Esercitazione: aggiungere l'iscrizione a un'app per dispositivi mobili iOS/macOS usando l'autenticazione nativa
Si applica a: iOS (Swift) macOS (Swift)
Questa esercitazione illustra come iscrivere un utente usando il passcode monouso o il nome utente (e-mail) e la password e acquisire gli attributi utente nell'app per dispositivi mobili iOS/macOS 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
- Esercitazione: Preparare l'app iOS per l'autenticazione nativa
- Se si desidera raccogliere gli attributi utente durante l'iscrizione, configurare gli attributi utente quando si crea il flusso iscrizione e accesso utente.
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:
Creare un'interfaccia utente (IU) per:
- Acquisire un’e-mail dall'utente. Aggiungere la convalida agli input per accertarsi che l'utente immetta un indirizzo e-mail 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.
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 iscrivere l'utente utilizzando il passcode monouso tramite e-mail, si userà il metodo
signUp(username:delegate)
della libreria, che risponde in modo asincrono chiamando uno dei metodi sull'oggetto delegato passato, che deve implementare ilSignUpStartDelegate
protocollo. La riga di codice seguente avvia il processo di iscrizione dell'utente:nativeAuth.signUp(username: email, delegate: self)
Nel metodo
signUp(username:delegate)
si passa l'indirizzo e-mail dell'utente dal modulo di invio e il delegato (una classe che implementa ilSignUpStartDelegate
protocollo).Per iscrivere un utente tramite e-mail 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) }
Si usa il metodo
signUp(username:password:delegate)
della libreria, che risponde in modo asincrono chiamando uno dei metodi sull'oggetto delegato passato, che deve implementare ilSignUpStartDelegate
protocollo. La riga di codice seguente avvia il processo di iscrizione dell'utente:nativeAuth.signUp(username: email, password: password, delegate: self)
Nel metodo
signUp(username:password:delegate)
viene passato l'indirizzo e-mail dell'utente, la password e il delegato (una classe che implementa ilSignUpStartDelegate
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)
osignUp(username:delegate)
comporta una chiamata ai metodi delegationSignUpCodeRequired()
oonSignUpStartError()
.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 parametronewState
di tipoSignUpCodeRequiredState
, 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 protocolloSignUpVerifyCodeDelegate
. Nello scenario più comune, si riceverà una chiamata aonSignUpCompleted(newState)
, che indica che l'utente ha eseguito l'accesso e il flusso è completo.
Raccogliere gli attributi utente durante l'iscrizione
Se si effettua l'iscrizione di un utente usando il passcode monouso tramite e-mail o il nome utente (e-mail) e la password, è possibile acquisire gli attributi utente prima che venga creato l'account dell’utente. Il metodo signUp(username:attributes:delegate)
accetta gli attributi come parametro.
Per recuperare gli attributi utente, usare il frammento di codice seguente:
let attributes = [ "country": "United States", "city": "Redmond" ] nativeAuth.signUp(username: email, attributes: attributes, delegate: self)
signUp(username:attributes:delegate)
oignUp(username:password:attributes:delegate)
comporta una chiamata ai metodi delegationSignUpCodeRequired()
oonSignUpStartError()
oppure una chiamata aonSignUpAttributesInvalid(attributeNames: [String])
se implementato nel delegato.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 chiamatoonSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)
per indicare che è stato inviato un codice per verificare l'indirizzo e-mail dell'utente. Oltre a dettagli, quali il destinatario del codice e il numero di cifre che compongono il codice, questo metodo delegato ha un parametronewState
di tipoSignUpCodeRequiredState
, 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 la convalida dell'input non è riuscita per uno o più attributi inviati. 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 oggettiMSALNativeAuthRequiredAttribute
, che descrivono i dettagli relativi agli attributi utente richiesti dall'API.
Entrambi i metodi delegati contengono un riferimento al nuovo stato. Verrà usato il parametro newState
per chiamare di nuovo submitAttributes(attributes:delegate)
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: far accedere l'utente automaticamente dopo l'iscrizione in un'app iOS/macOS app.