Поделиться через


Учебник: Добавление регистрации в приложении iOS/macOS с использованием нативной аутентификации

Применяется: зеленый круг с символом белой галочки, указывающим, что следующее содержимое применяется к внешним клиентам. Внешние клиенты (дополнительные сведения)

В этом руководстве показано, как зарегистрировать пользователя с помощью одноразового пароля или адреса электронной почты (или имени пользователя) и пароля, а также собирать атрибуты пользователей в приложении iOS/macOS с использованием встроенной аутентификации.

  • Зарегистрируйте пользователя с помощью однократного секретного кода электронной почты или имени пользователя (электронной почты) и пароля.
  • Сбор атрибутов пользователей во время регистрации.
  • Обработка ошибок регистрации.

Необходимые условия

Регистрация пользователя

Чтобы зарегистрировать пользователя по одноразовому коду, отправленному на электронную почту, или используя имя пользователя (электронную почту) и пароль, необходимо получить электронный адрес пользователя, а затем отправить на него письмо с одноразовым кодом. Пользователь вводит действительный одноразовый код из электронной почты для подтверждения имени пользователя.

Чтобы зарегистрировать пользователя, необходимо выполнить следующие действия.

  1. Создайте пользовательский интерфейс для:

    • Соберите электронный адрес у пользователя. Добавьте проверку в входные данные, чтобы убедиться, что пользователь вводит допустимый адрес электронной почты.
    • Соберите пароль при регистрации с помощью имени пользователя (электронной почты) и пароля.
    • Соберите одноразовый секретный код электронной почты от пользователя.
    • При необходимости соберите атрибуты пользователя.
    • Повторно отправьте одноразовый секретный код, если пользователь не получает его.
    • Запустите поток регистрации.
  2. В приложении добавьте кнопку, событие выбора которой активирует следующий фрагмент кода:

    @IBAction func signUpPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "Email or password not set"
            return
        }
    
        let parameters = MSALNativeAuthSignUpParameters(username: email)
        nativeAuth.signUp(parameters: parameters, delegate: self)
    }
    
    • Для регистрации пользователя с использованием одноразового кода, отправленного по электронной почте , мы используем метод signUp(parameters:delegate) из библиотеки, который отвечает асинхронно, вызывая один из методов переданного объекта делегата, который должен реализовать протокол SignUpStartDelegate. Следующая строка кода инициирует процесс регистрации пользователя:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      В методе signUp(parameters:delegate) мы передаем экземпляр MSALNativeAuthSignUpParameters, содержащий адрес электронной почты пользователя из формы отправки вместе с делегатом (класс, реализующий протокол SignUpStartDelegate).

    • Чтобы зарегистрировать пользователя с помощью электронной почты и пароля, используйте следующие фрагменты кода:

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

      мы используем метод signUp(parameters:delegate) библиотеки, который отвечает асинхронно путем вызова одного из методов в переданном объекте делегата, который должен реализовать протокол SignUpStartDelegate. Следующая строка кода инициирует процесс регистрации пользователя:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      В методе signUp(parameters:delegate) мы передаем экземпляр MSALNativeAuthSignUpParameters, содержащий адрес электронной почты пользователя и пароль вместе с делегатом (класс, реализующий протокол SignUpStartDelegate).

    • Чтобы реализовать протокол SignUpStartDelegate в качестве расширения для нашего класса, используйте следующее:

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

      Вызов signUp(parameters:delegate)может привести к вызову методов делегата onSignUpCodeRequired() или onSignUpStartError(). Вызывается onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength), чтобы указать, что код отправлен для проверки адреса электронной почты пользователя. Наряду с некоторыми сведениями о том, где был отправлен код, и сколько цифр он содержит, этот метод делегата также имеет параметр newState типа SignUpCodeRequiredState, который предоставляет нам доступ к двум новым методам:

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

      Чтобы отправить код, предоставленный пользователем, используйте следующую команду:

      newState.submitCode(code: userSuppliedCode, delegate: self)
      
      • Чтобы реализовать протокол SignUpVerifyCodeDelegate в качестве расширения для нашего класса, используйте следующее:

        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) принимает параметр делегата, и необходимо реализовать необходимые методы в протоколе SignUpVerifyCodeDelegate. В наиболее распространенном сценарии мы получаем вызов onSignUpCompleted(newState), указывающий, что пользователь был зарегистрирован и поток завершен.

Сбор атрибутов пользователей во время регистрации

Вы можете собирать атрибуты пользователей перед созданием учетной записи, независимо от того, регистрируете ли вы пользователя с помощью одноразового пароля для электронной почты или имени пользователя (электронной почты) и пароля. Метод signUp(parameters:delegate) можно вызывать с помощью MSALNativeAuthSignUpParameters, у которого есть свойство атрибутов.

  1. Чтобы собрать атрибуты пользователя, используйте следующий фрагмент кода:

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

    signUp(parameters:delegate)приводит к вызову методов делегата onSignUpCodeRequired() или onSignUpStartError(), или onSignUpAttributesInvalid(attributeNames: [String]) в случае, если он реализован в делегате.

  2. Чтобы реализовать протокол SignUpStartDelegate в качестве расширения для нашего класса, используйте следующий фрагмент кода:

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

    Если атрибуты недопустимы, вызывается метод onSignUpAttributesInvalid(attributeNames: [String]). В этом случае мы отображаем список недопустимых атрибутов пользователю. В противном случае вызывается onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength), чтобы указать, что код отправлен для проверки адреса электронной почты пользователя. Помимо сведений, таких как получатель кода и число цифр кода, этот метод делегата имеет параметр newState типа SignUpCodeRequiredState, который предоставляет нам доступ к двум новым методам:

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

Атрибуты пользователя на одной или нескольких страницах

Чтобы распределить атрибуты по одной или нескольким страницам, необходимо задать атрибуты, которые мы собираемся собирать на разных страницах как обязательные в конфигурации клиента идентификации и доступа (CIAM).

Мы вызываем signUp(parameters:delegate) без передачи атрибутов в экземпляре MSALNativeAuthSignUpParameters. Следующим шагом будет вызов newState.submitCode(code: userSuppliedCode, delegate: self), чтобы проверить электронную почту пользователя.

Мы реализуем протокол SignUpVerifyCodeDelegate в качестве расширения для нашего класса, как и раньше, но на этот раз мы должны реализовать необязательный метод 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!"
    }
}

Этот метод делегата имеет параметр newState типа SignUpAttributesRequiredState, который предоставляет нам доступ к новому методу:

  • submitAttributes(attributes:delegate)

Чтобы отправить атрибуты, предоставленные пользователем, используйте следующий фрагмент кода:

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

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

Мы также реализуем протокол SignUpAttributesRequiredDelegate в качестве расширения для нашего класса:

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

Когда пользователь не предоставляет все необходимые атрибуты или если атрибуты недействительны, вызываются следующие методы делегата:

  • onSignUpAttributesInvalid: указывает, что один или несколько атрибутов, отправленных не прошли проверку входных данных. Эта ошибка содержит параметр attributeNames, который представляет собой список всех атрибутов, отправленных разработчиком, которые не выполнили проверку входных данных.
  • onSignUpAttributesRequired: указывает, что серверу требуется отправить один или несколько атрибутов, прежде чем будет создана учетная запись пользователя. Это происходит, когда один или несколько атрибутов задаются как обязательные в конфигурации клиента. Этот результат содержит параметр атрибутов, который представляет собой список объектов MSALNativeAuthRequiredAttribute, которые содержат сведения о атрибутах пользователя, необходимых API.

Оба метода делегата содержат новую ссылку на состояние. Мы используем параметр newState для вызова submitAttributes(attributes:delegate) снова с новыми атрибутами.

Обработка ошибок регистрации

Во время регистрации не все действия успешно выполнены. Например, пользователь может попытаться зарегистрироваться с помощью адреса электронной почты, который уже используется, или отправить недопустимый код.

В предыдущей реализации протокола SignUpStartDelegate мы просто отображали ошибку при обработке функции делегата onSignUpStartError(error).

Чтобы улучшить взаимодействие с пользователем, управляя определенным типом ошибок, используйте следующий фрагмент кода:

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

Опционально: Вход после процесса регистрации.

После успешной регистрации вы можете войти в систему как пользователь, не инициируя процесс входа. Дополнительные сведения см. в статье руководства : Автоматический вход пользователя после регистрации в приложении для iOS или macOS.

Следующий шаг

Руководство: Добавление функций входа и выхода в приложении iOS/macOS с использованием нативной аутентификации