Я использую AWS Cognito для реализации регистрации и входа пользователей в свое приложение iOS (Swift).
Когда пользователь зарегистрировался, я хочу добавить пользователя в указанную группу пула пользователей, которая уже была создана в моем пуле пользователей cognito.
Я попробовал приведенный ниже быстрый код, но, похоже, он не работает.
После регистрации пользователь нажимает кнопку [addToGroup], чтобы присоединиться к группе пула пользователей с именем [GroupA].
@IBAction func addToGroupButton(_ sender: Any) {
let request = AWSCognitoIdentityProviderAdminAddUserToGroupRequest()
request?.groupName = "GroupA"
request?.userPoolId = "ap-northeast-1_8H0k*****"
request?.username = eMailAdd
let identityProvider = AWSCognitoIdentityProvider()
identityProvider.adminAddUser(toGroup: request!).continueWith { (task) -> Any? in
DispatchQueue.main.async(execute: {
if let error = task.error {
print("\(error.localizedDescription)")
}
})
}
}
У пользователя нет проблем с регистрацией, и я могу подтвердить информацию, которую пользователь зарегистрировал. НО, имя пользователя просто не отображается в GroupA.
Может ли кто-нибудь сказать мне, что не так с моим кодом ?? СПАСИБО!!





Я предполагаю, что вы получаете какую-то ошибку, например AWSCognitoIdentityProviderErrorNotAuthorized. Поскольку это вызов API «администратора», который «требует учетных данных разработчика», как предлагается здесь [0].
Я бы посоветовал вам жестко закодировать свои учетные данные, чтобы сначала проверить, работает ли этот вызов API.
AWSStaticCredentialsProvider *credentialsProvider = [AWSStaticCredentialsProvider credentialsWithAccessKey:"your-access-key" secretKey:"your-secret-key"];
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
Обратите внимание, что не следует жестко кодировать свои учетные данные в производственной среде.
Обновление от 21.07.2019:
let staticCredentialProvider = AWSStaticCredentialsProvider.init(accessKey: "yourAccessKey", secretKey: "yourSecretKey")
let configuration = AWSServiceConfiguration.init(region: .APSoutheast2, credentialsProvider: staticCredentialProvider)
AWSServiceManager.default()?.defaultServiceConfiguration = configuration
let request = AWSCognitoIdentityProviderAdminAddUserToGroupRequest()
request?.groupName = "GroupA"
request?.userPoolId = "ap-southeast-2_xxxxxxxxx"
request?.username = "yourUserName"
AWSCognitoIdentityProvider.default().adminAddUser(toGroup: request!).continueWith { (task) -> Any? in
DispatchQueue.main.async(execute: {
if let error = task.error {
print("\(error.localizedDescription)")
}
})
}
Я тестировал, приведенный выше код работает в моей тестовой среде. Я перечисляю его здесь для справки. Следующим шагом будет попытка удалить жестко закодированные учетные данные из кодовой базы. Вместо использования AWSStaticCredentialsProvider временные учетные данные можно получить с помощью пула удостоверений Cognito. Я считаю, что при соответствующем разрешении этот поток может работать без учетных данных разработчика.
Обновление от 26.07.2019:
// using Cognito userpool with identity pool, to provider credential to AWSServiceManager
let serviceConfiguration = AWSServiceConfiguration(region: .APSoutheast2, credentialsProvider: nil)
let userPoolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: "YourUserPoolClientId", clientSecret: "YourUserPoolClientSecret", poolId: "YourUserPoolId")
AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: userPoolConfiguration, forKey: "RandomStringForIdentifyingYourPoolWithinThisApp")
let pool = AWSCognitoIdentityUserPool(forKey: "RandomStringForIdentifyingYourPoolWithinThisApp")
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .APSoutheast2, identityPoolId: "YourIdentityPoolId", identityProviderManager:pool)
let configuration = AWSServiceConfiguration.init(region: .APSoutheast2, credentialsProvider: credentialsProvider)
AWSServiceManager.default()?.defaultServiceConfiguration = configuration
// sign in a user
pool.getUser("UserNameOfAUserInYourPool").getSession("UserNameOfAUserInYourPool", password: "PasswordOfAUserInYourPool", validationData: nil).continueWith { (task) -> Any? in
if let error = task.error {
print("user sign in error: \(error.localizedDescription)")
} else {
print("user session is: \(String(describing: task.result))")
}
// add a user to GroupA
let request = AWSCognitoIdentityProviderAdminAddUserToGroupRequest()
request?.groupName = "GroupA"
request?.userPoolId = "YourUserPoolId"
request?.username = "UserNameOfAUserInYourPool"
return AWSCognitoIdentityProvider.default().adminAddUser(toGroup: request!)
}.continueWith { (task) -> Any? in
if let error = task.error {
print("cannot add user to group \(error.localizedDescription)")
}
}
Как я и предполагал, это решение без жестко заданных учетных данных AWS. Пул Cognito Identity предоставляет температурные учетные данные AWS после входа пользователя в пул пользователей Cognito [3], что позволяет выполнять вызов API adminAddToGroup.
Наряду с приведенным выше кодом вам также необходимо настроить пул удостоверений Cognito на консоли AWS или с помощью интерфейса командной строки AWS. Подробности вы можете найти на скриншоте.
Вам также необходимо создать роль авторизации IAM для аутентифицированного пользователя. Вот пример политики.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"cognito-idp:AdminRemoveUserFromGroup",
"cognito-idp:AdminAddUserToGroup"
],
"Resource": "Your_userpool_ARN"
}
]
}
Ссылка: [0]https://aws-amplify.github.io/aws-sdk-ios/docs/reference/Classes/AWSCognitoIdentityProvider.html#//api/name/adminAddUserToGroup: [2]https://aws.amazon.com/blogs/mobile/how-amazon-cognito-keeps-mobile-app-users-data-safe/ [3]https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-integrating-user-pools-with-identity-pools.html
@keishinzzz не беспокойтесь, я обновил свой ответ. Причина, по которой вы получаете исключение, заключается в том, что AWSCognitoIdentityProvider не может быть создан с использованием обычного метода init(). Вместо этого вы должны использовать синглтон. Как я уже говорил вчера, вам нужно настроить AWSServiceConfiguration, чтобы подписать этот вызов API администратора. Я могу обновить ответ, как только у меня будет время избавиться от жестко запрограммированных учетных данных разработчика.
Это сработало! Большое спасибо! Без вашей помощи я не знаю, сколько бы еще времени я потратил на этот вопрос. Следующий шаг — избавиться от жестко запрограммированной части учетных данных разработчика. До этого я понял, что [request?.username] должен быть UUID в пользовательском пуле. Но прямо сейчас я использую электронную почту для регистрации в своем приложении, поэтому мне нужно найти способ вызвать UUID в программе. Я только начал изучать AWS за пару ртов в одиночку. Я так рада, что ты мне помог. Большое спасибо .
Я попробовал еще раз, и код просто отлично сработал. Кажется, я могу добавить пользователя либо по его имени пользователя, либо по его UUID (sub). У меня нет абсолютной уверенности, но, похоже, это работает в любом случае...
@keishinzzz Добро пожаловать :) в конечном итоге вы захотите избавиться от AWSStaticCredentialsProvider, используя вместо этого AWSCognitoCredentialsProvider. В этом случае пользователи, вошедшие в систему, могут получить временные учетные данные из пула удостоверений, что теоретически позволяет им добавлять себя в группу. Роль аутентификации в пуле удостоверений должна иметь достаточные права для вызова вызова API администратора. На этой неделе очень занят, постараюсь протестировать, как только будет время.
@keishinzzz Как и обещал, я добавил новое решение без жестко запрограммированных учетных данных AWS. Чтобы использовать сервисы AWS в iOS, я бы посоветовал вам проверить последнюю версию Amplify iOS SDK (aws-amplify.github.io/docs/ios/start). Он имеет лучший документ и обеспечивает лучший опыт разработки. «AdminAddToGroup» не поддерживается «из коробки», но я думаю, что он может работать с моим вышеуказанным решением с некоторыми настройками. Я могу привести пример, когда у меня будет время.
@keishinzzz не беспокойтесь :) Я знаю, что вы не будете меня беспокоить, но задав вопрос здесь, вы можете помочь другим с такой же проблемой, верно? Вы всегда можете задать вопрос здесь и связаться со мной, я сделаю все возможное, чтобы ответить, когда буду доступен.
Спасибо за ваш ответ. Это может быть ключом к этой проблеме. Но сейчас я даже не могу распечатать ошибку, потому что в этой части кода что-то не так. Сообщение об ошибке [Завершение работы приложения из-за неперехваченного исключения "NSInternalInconsistencyException", причина: "
- initне является допустимым инициализатором. Вместо этого используйте+ defaultCognitoIdentityProviderили+ CognitoIdentityProviderForKey:.']. Я думаю, что вчера я распечатал "(error.localizedDescription)" с тем же кодом. Но сегодня, когда я запускаю программу, появилось сообщение выше. Так запутался... У тебя есть какие-нибудь идеи?