Как в AWS iOS SDK обрабатывать статус пользователя FORCE_CHANGE_PASSWORD

Я следовал образцу здесь

https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample

Чтобы интегрировать интерактивный когнитивный вход в мое приложение для iOS. Это все работает хорошо, но когда в пуле создается новый пользователь, он изначально имеет статус FORCE_CHANGE_PASSWORD.

Для Android вы можете выполнить процедуру ниже

http://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-android-sdk-authenticate-admin-created-user.html< /а>

Но для iOS я не могу узнать, как это сделать. Используя пример, если я попытаюсь войти в систему с пользователем в статусе FORCE_CHANGE_PASSWORD, я увижу следующий вывод в журналах консоли (с некоторыми значениями, удаленными для краткости):

{"ChallengeName":"NEW_PASSWORD_REQUIRED","ChallengeParameters":{"requiredAttributes":"[]","userAttributes":"{\"email_verified\":\"true\",\"custom:autoconfirm\":\ "Y\","Сеанс":"xyz"}

Ниже приведен код SignInViewController из приведенного выше примера.

import Foundation
import AWSCognitoIdentityProvider

class SignInViewController: UIViewController {
    @IBOutlet weak var username: UITextField!
    @IBOutlet weak var password: UITextField!
    var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?
    var usernameText: String?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.password.text = nil
        self.username.text = usernameText
        self.navigationController?.setNavigationBarHidden(true,   animated: false)
    }

    @IBAction func signInPressed(_ sender: AnyObject) {
        if (self.username.text != nil && self.password.text != nil) {
            let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: self.username.text!, password: self.password.text! )
            self.passwordAuthenticationCompletion?.set(result: authDetails)
        } else {
            let alertController = UIAlertController(title: "Missing information",
                                                message: "Please enter a valid user name and password",
                                                preferredStyle: .alert)
            let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
            alertController.addAction(retryAction)
        }
    }
}

extension SignInViewController: AWSCognitoIdentityPasswordAuthentication {

    public func getDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletionSource: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>)     {
        self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource
        DispatchQueue.main.async {
            if (self.usernameText == nil) {
                self.usernameText = authenticationInput.lastKnownUsername
            }
        }
    }

    public func didCompleteStepWithError(_ error: Error?) {
        DispatchQueue.main.async {
        if let error = error as? NSError {
            let alertController = UIAlertController(title: error.userInfo["__type"] as? String,
                                                    message: error.userInfo["message"] as? String,
                                                    preferredStyle: .alert)
            let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
            alertController.addAction(retryAction)

            self.present(alertController, animated: true, completion:  nil)
            } else {
                self.username.text = nil
                self.dismiss(animated: true, completion: nil)
            }
        }
    }
}

Когда didCompleteStepWithError выполняется, error имеет значение null, где я ожидал бы, что он укажет что-то, чтобы сообщить нам, что пользователю требуется изменить пароль.

Мой вопрос действительно в том, как поймать "ChallengeName":"NEW_PASSWORD_REQUIRED" json, который выводится на консоль?


person Gary Wright    schedule 13.03.2017    source источник


Ответы (2)


Разобрался с этим сейчас. Разместите это здесь, если это поможет кому-то еще.

Во-первых, вам нужно создать контроллер представления, который позволит пользователю указать новый пароль. ViewController должен иметь свойство AWSTaskCompletionSource<AWSCognitoIdentityNewPasswordRequiredDetails>:

var newPasswordCompletion: AWSTaskCompletionSource<AWSCognitoIdentityNewPasswordRequiredDetails>?

Следуя шаблону в примере, упомянутом в вопросе, я реализовал AWSCognitoIdentityNewPasswordRequired как расширение контроллера представления следующим образом:

extension NewPasswordRequiredViewController: AWSCognitoIdentityNewPasswordRequired {
    func getNewPasswordDetails(_ newPasswordRequiredInput: AWSCognitoIdentityNewPasswordRequiredInput, newPasswordRequiredCompletionSource:
    AWSTaskCompletionSource<AWSCognitoIdentityNewPasswordRequiredDetails>) {                    
        self.newPasswordCompletion = newPasswordRequiredCompletionSource
    }

    func didCompleteNewPasswordStepWithError(_ error: Error?) {
        if let error = error as? NSError {
            // Handle error
        } else {
            // Handle success, in my case simply dismiss the view controller
            self.dismiss(animated: true, completion: nil)
        }
    }

}

Снова следуя дизайну примера, подробно описанному в вопросе, добавьте функцию к расширению AWSCognitoIdentityInteractiveAuthenticationDelegate в AppDelegate:

extension AppDelegate: AWSCognitoIdentityInteractiveAuthenticationDelegate {
    func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
        //Existing implementation
    }
    func startNewPasswordRequired() -> AWSCognitoIdentityNewPasswordRequired {
        // Your code to handle how the NewPasswordRequiredViewController is created / presented, the view controller should be returned
        return self.newPasswordRequiredViewController!
    }
}
person Gary Wright    schedule 15.03.2017
comment
Спасибо за подробности. Я не могу себе представить, что документация, связанная с Cognito, настолько неудобна для пользователя. API, который они предоставили, также плохой - person fans3210; 15.03.2018

Идеальный пример реализации ResetPassword при создании пользователя в Cognito Console.

Но вы несете ответственность за интеграцию этого механизма ResetPassword в ваше существующее приложение.

https://github.com/davidtucker/CognitoSampleApplication/tree/article1/CognitoApplication

person Anand    schedule 26.03.2018