Руководство. Добавление входа и выхода в приложение iOS/macOS с помощью собственной проверки подлинности
Область применения: iOS (Swift) macOS (Swift) (Swift)
В этом руководстве показано, как войти и выйти пользователя с помощью однократного секретного кода или пароля электронной почты в приложении iOS/macOS с помощью собственной проверки подлинности.
В этом руководстве описано следующее:
- Войдите в систему, используя одноразовый секретный код электронной почты или имя пользователя (электронная почта) и пароль.
- Выйдите из пользователя.
- Обработка ошибки входа
Необходимые компоненты
- Руководство. Подготовка приложения iOS/macOS для собственной проверки подлинности.
- Если вы хотите войти с помощью электронной почты с паролем, настройте поток пользователя для использования электронной почты с паролем при создании потока пользователя и регистрации.
Вход пользователя
Чтобы войти в систему пользователя с помощью потока однократного секретного кода электронной почты, запишите сообщение электронной почты и отправьте сообщение электронной почты, содержащее одноразовый секретный код для пользователя, чтобы проверить свой адрес электронной почты. Когда пользователь вводит действительный одноразовый секретный код, приложение войдет в систему.
Чтобы войти в систему пользователя с помощью потока паролей , запишите сообщение электронной почты и пароль. Если имя пользователя и пароль действительны, приложение войдите в систему пользователя.
Чтобы войти в систему, необходимо выполнить следующие действия.
Создайте пользовательский интерфейс для:
- Сбор сообщения электронной почты от пользователя. Добавьте проверку в входные данные, чтобы убедиться, что пользователь вводит допустимый адрес электронной почты.
- Соберите пароль при входе с помощью имени пользователя (электронной почты) и пароля.
- Соберите одноразовый секретный код электронной почты от пользователя, если вы войдите в систему с помощью однократного секретного кода электронной почты.
- Добавьте кнопку, чтобы разрешить пользователю повторно отправить одноразовый секретный код при входе с помощью однократного секретного кода электронной почты.
В пользовательском интерфейсе добавьте кнопку, событие выбора которой запускает вход, как показано в следующем фрагменте кода:
@IBAction func signInPressed(_: Any) { guard let email = emailTextField.text else { resultTextView.text = "email not set" return } nativeAuth.signIn(username: email, delegate: self) }
Для входа пользователя с помощью потока однократного секретного кода электронной почты мы используем следующий фрагмент кода:
nativeAuth.signIn(username: email, delegate: self)
Метод
signIn(username:delegate)
, который отвечает асинхронно путем вызова одного из методов в переданном объекте делегата, должен реализоватьSignInStartDelegate
протокол. Передайте адрес электронной почты, который пользователь предоставляет в форме отправки электронной почты и передаетсяself
в качестве делегата.Для входа пользователя с помощью потока паролей используйте следующий фрагмент кода:
nativeAuth.signIn(username: email, password: password, delegate: self)
В методе
signIn(username:password:delegate)
вы передаете адрес электронной почты, предоставленный пользователем, своим паролем, и передаете объект делегата, соответствующий протоколуSignInStartDelegate
. В этом примере мы передаемself
.Чтобы реализовать
SignInStartDelegate
протокол при использовании потока одноразового секретного кода электронной почты, используйте следующий фрагмент кода:extension ViewController: SignInStartDelegate { func onSignInStartError(error: MSAL.SignInStartError) { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } func onSignInCodeRequired( newState: MSAL.SignInCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } }
signIn(username:delegate)
Результаты вызова методов делегирования. В наиболее распространенном сценарииonSignInCodeRequired(newState:sentTo:channelTargetType:codeLength)
вызывается, чтобы указать, что код отправлен для проверки адреса электронной почты пользователя. Наряду с некоторыми сведениями о том, где был отправлен код, и сколько цифр он содержит, этот метод делегата также имеетnewState
параметр типаSignInCodeRequiredState
, который предоставляет нам доступ к следующим двум новым методам:submitCode(code:delegate)
resendCode(delegate)
Используйте
submitCode(code:delegate)
для отправки одноразового секретного кода, который пользователь предоставляет в форме одноразового секретного кода, используйте следующий фрагмент кода:newState.submitCode(code: userSuppliedCode, delegate: self)
Принимает
submitCode(code:delegate)
одноразовый секретный код и параметр делегата. После отправки кода необходимо проверить одноразовый секретный код, реализуяSignInVerifyCodeDelegate
протокол.Чтобы реализовать
SignInVerifyCodeDelegate
протокол в качестве расширения для класса, используйте следующий фрагмент кода:extension ViewController: SignInVerifyCodeDelegate { func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully." result.getAccessToken(delegate: self) } }
В наиболее распространенном сценарии мы получаем вызов, указывающий
onSignInCompleted(result)
, что пользователь вошел в систему. Результат можно использовать для извлеченияaccess token
.Принимает
getAccessToken(delegate)
параметр делегата, и мы должны реализовать необходимые методы в протоколеCredentialsDelegate
.В наиболее распространенном сценарии мы получаем вызов,
onAccessTokenRetrieveCompleted(result)
указывающий, что пользователь получил .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)" } }
Чтобы реализовать
SignInStartDelegate
протокол при использовании электронной почты с потоком паролей , используйте следующий фрагмент кода:extension ViewController: SignInStartDelegate { func onSignInStartError(error: MSAL.SignInStartError) { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) { // User successfully signed in } }
В наиболее распространенном сценарии мы получаем вызов, указывающий
onSignInCompleted(result)
, что пользователь вошел в систему. Результат можно использовать для извлеченияaccess token
.Принимает
getAccessToken(delegate)
параметр делегата, и мы должны реализовать необходимые методы в протоколеCredentialsDelegate
.В наиболее распространенном сценарии мы получаем вызов,
onAccessTokenRetrieveCompleted(result)
указывающий, что пользователь получил .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)" } }
Обработка ошибок входа
Во время входа не все действия успешно выполнены. Например, пользователь может попытаться войти с помощью адреса электронной почты, который не существует, или отправить недопустимый код.
Для обработки ошибок в или
signIn(username, password)
методеsignIn(username)
используйте следующий фрагмент кода:func onSignInStartError(error: MSAL.SignInStartError) { if error.isUserNotFound || error.isInvalidUsername { resultTextView.text = "Invalid username" } else { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } }
Для обработки ошибок в
submitCode()
методе используйте следующий фрагмент кода:func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) { if error.isInvalidCode { // Inform the user that the submitted code was incorrect and ask for a new code to be supplied let userSuppliedCode = retrieveNewCode() newState?.submitCode(code: userSuppliedCode, delegate: self) } else { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } }
Если пользователь вводит неверный код проверки электронной почты, обработчик ошибок содержит ссылку на объект
SignInCodeRequiredState
, который можно использовать для отправки обновленного кода. В более раннейSignInVerifyCodeDelegate
реализации протокола мы просто отображали ошибку при обработке функции делегатаonSignInVerifyCodeError(error:newState)
.
Чтение утверждений маркера идентификатора
После получения маркера идентификатора приложение сможет получить утверждения, связанные с текущей учетной записью. Для этого используйте следующий фрагмент кода:
func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
let claims = result.account.accountClaims
let preferredUsername = claims?["preferred_username"] as? String
}
Ключ, используемый для доступа к значению утверждения, — это имя, указанное при добавлении атрибута пользователя в качестве утверждения токена.
Узнайте, как добавить встроенные и пользовательские атрибуты в качестве утверждений токена в статье "Добавление атрибутов пользователя" в статью о утверждениях токенов.
Выход пользователя
Чтобы выйти пользователя, используйте ссылку на MSALNativeAuthUserAccountResult
полученную в onSignInCompleted
обратном вызове учетную запись или используйте getNativeAuthUserAccount()
для получения любой учетной записи входа из кэша и сохранения ссылки в переменной-члене accountResult
.
Настройте группу цепочки ключей для проекта, как описано здесь.
Добавьте новую переменную-член в
ViewController
класс:var accountResult: MSALNativeAuthUserAccountResult?
Обновите
viewDidLoad
, чтобы получить любую кэшированную учетную запись, добавив эту строку послеnativeAuth
успешной инициализации:accountResult = nativeAuth.getNativeAuthUserAccount()
Обновите обработчик, чтобы сохранить результат учетной
signInCompleted
записи:func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully" accountResult = result }
Добавьте кнопку выхода и используйте следующий код для выхода пользователя:
@IBAction func signOutPressed(_: Any) { guard let accountResult = accountResult else { print("Not currently signed in") return } accountResult.signOut() self.accountResult = nil resultTextView.text = "Signed out" }
Вы успешно выполнили все необходимые действия для выхода пользователя в приложение. Скомпилируйте и запустите приложение. Если все хорошо, вы сможете выбрать кнопку выхода, чтобы успешно выйти.
Настройка настраиваемого поставщика утверждений
Если вы хотите добавить утверждения из внешней системы в маркер, выданный приложению, используйте настраиваемый поставщик утверждений. Настраиваемый поставщик утверждений состоит из настраиваемого расширения проверки подлинности, вызывающего внешний REST API для получения утверждений из внешних систем.
Выполните действия, описанные в разделе "Настройка настраиваемого поставщика утверждений" для добавления утверждений из внешней системы в маркеры безопасности.
Связанный контент
- Настройте настраиваемый поставщик утверждений.