Свяжите пользовательскую информацию из Cognito с AWS Amplify GraphQL - PullRequest
1 голос
/ 19 апреля 2020

Я нахожусь на xcode 11.4, Swift 4. Цель:

  1. зарегистрировать нового пользователя в Cognito User Pool, а затем сохранить связанную запись пользователя с помощью Amplify GraphQL.

  2. CRUD запись пользователя после входа в Cognito User Pool.

Проблема в том, что я не знаю, как связать Cognito с Amplify GraphQL. Например, в Google Firebase auth и Firestore, я получу уникальный идентификатор пользователя UID после регистрации, затем я создам связанную запись пользователя в Firestore с ключом как UID. Затем при входе / аутентификации пользователя я могу получить UID от firebase auth и найти соответствующую запись в firestore.

В настоящее время со стеком AWS я создал пользовательскую модель в schema.graphql как:

type User @model @auth(rules: [{ allow: owner, ownerField: "id", operations: [create, update, delete]}]){
    id: ID!
    firstName  : String
    lastName   : String
    handle     : String
    email      : String!
}

, так что только аутентифицированный пользователь может создавать, обновлять и удалять. Далее где-то в SignUpController я создаю нового пользователя:

AWSMobileClient.default().signUp( username: email
                                , password: password
                                , userAttributes: ["email": email]) { (signUpResult, error) in
    if let signUpResult = signUpResult {

        switch(signUpResult.signUpConfirmationState) {
            case .confirmed:
                self.showAlert(msg: "You already have an account. Please go back and press log in")
            case .unconfirmed:
                break 
            case .unknown:
                self.showAlert(msg: "Network error")
        }
    } else if let error = error { ... }

и затем подтверждаю пользователя с кодом:

AWSMobileClient.default().confirmSignUp(username: email, confirmationCode: code) { (signUpResult, error) in
    if let signUpResult = signUpResult {
        switch(signUpResult.signUpConfirmationState) {
            case .confirmed:
               // This is where I need to create an associated user account
               break
            case .unconfirmed:
                self.showAlert(title: "Error", msg: "User is not confirmed and needs verification via \(signUpResult.codeDeliveryDetails!.deliveryMedium) sent at \(signUpResult.codeDeliveryDetails!.destination!)")
            case .unknown:
                self.showAlert(title: "Error", msg: "Network error")
        }
    } else { //if let error = error {
        self.showAlert(title: "Error", msg: "Network error")
    }

Прямо сейчас мое решение в case .confirmed состоит в том, чтобы подписать немедленно, а затем получить пользовательский client token с помощью:

class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync {

    /// this token may not be what you want ...
    func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {

        AWSMobileClient.default().getTokens { (token, error) in
            if let error = error {
                callback(nil,error)
            }
            callback(token?.accessToken?.tokenString, error)
        }
    }
}

Это оказывается неправильным решением, так как клиентский токен пользователя постоянно меняется.

В целом, это стандартная проблема hello-world, и должно быть стандартное готовое решение, предоставляемое AWS. Я ищу документы и github, но не могу найти удовлетворительный ответ.

1 Ответ

1 голос
/ 20 апреля 2020

Правильный путь - НЕ ДОВЕРЯТЬ КЛИЕНТУ для создания информации о ассоциированном пользователе из Cognito, вы должны сделать это на стороне сервера.

Вам следует создать новый лямбда-пост-подтверждение триггера для Cognito и кодировать его для создать связанную учетную запись. Вы можете использовать event.userName или создать пользовательский атрибут типа uuid, например custom:id, чтобы связать свою учетную запись.

Ссылка: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-confirmation.html

...