Интеграция AWS Cognito swift3 Refresh обеспечивает исключение ResourceNotFoundException
Ниже приведен ответ здесь: https://github.com/aws/aws-sdk-ios/issues/357 В самом низу есть мини-руководство по быстрому и когнитивному труду.
Я сделал AWSCustomIdentityProvider как таковой:
import Foundation
import AWSCognitoIdentityProvider
import AWSCognito
class AWSCustomIdentityProvider: NSObject, AWSIdentityProviderManager
{
private var dict = NSDictionary()
func addToken(value:NSString)
{
dict = ["graph.facebook.com":value]
}
public func logins() -> AWSTask<NSDictionary>
{
return AWSTask(result: dict)
}
}
И у меня есть метод входа из Facebook:
public func loginButtonDidCompleteLogin(_ loginButton: FacebookLogin.LoginButton, result: FacebookLogin.LoginResult){
switch result {
case .failed(let error):
print("FACEBOOK LOGIN FAILED: \(error)")
case .cancelled:
print("User cancelled login.")
case .success(_, _, let accessToken):
let customIdentity = AWSCustomIdentityProvider()
let token = accessToken.authenticationToken
customIdentity.addToken(value: token as NSString)
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: REGIONTYPE, identityPoolId: "XXXXXXXXXXXXXXXXXXXXXXX", identityProviderManager:customIdentity)
credentialsProvider.clearKeychain()
credentialsProvider.clearCredentials()
let serviceConfiguration = AWSServiceConfiguration(region: REDIONTYPE, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration;
credentialsProvider.getIdentityId().continue( { (task: AWSTask!) -> AnyObject! in
if (task.error != nil) {
print("Error: " + (task.error?.localizedDescription)!)// gets called
}
else {
print(task.result)//identityid
}
return nil
})
}
}
Однако я получаю ошибку:
Ошибка Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "(null)" UserInfo={__type=NotAuthorizedException, message= Логины не совпадают. Пожалуйста, включите по крайней мере один действительный логин для этой личности или пула идентичностей.
Пожалуйста, дайте мне знать, если у вас есть идеи, как решить мою проблему. Я также пытался следовать документам и устанавливать логины напрямую "credentialsProvider.logins = {"graph.facebook.com": mytoken}
и это вызывает другое исключение при вызове лямбда-метода, но ДОЛЖНО правильно извлекать идентификатор. Однако выполнение этого в соответствии с документацией предупреждает о том, что используемый мной метод устарел.
Ошибка, которую я получаю:
UserInfo = {NSLocalizedDescription = сериализованный объект не является ни действительным объектом json, ни объектом NSData: }
Однако это случается иногда. Если я повторю попытку, то потенциально смогу получить идентификатор, но после вызова лямбда-метода получаю ту же ошибку. Я предполагаю, что это проблема с когнитивными проблемами.
ОБНОВИТЬ
Если в первой части я использую AWSCognitoLoginProviderKey.facebook.rawValue вместо graph.facebook.com, то он дает мне идентификатор Cognito, а затем я вызываю лямбда-метод. Я включу лямбда-метод только в том случае, если это та часть, в которой я ошибаюсь, но я прилично уверен, что именно когнито мешает мне вызывать лямбда-метод:
import AWSLambda
import Foundation
struct AWSHelper{
let lambda = AWSLambda.default()
let APPLICATION_NAME = "MYAPPLICATION"
init(){
}
func getFunctionName(funcName: String) -> String{
return "\(funcName)_\(APPLICATION_NAME)"
}
func login(facebookID: String, cognitoID:String, callback:@escaping (Bool) -> Void){
let req = AWSLambdaInvocationRequest();
req?.invocationType = AWSLambdaInvocationType.requestResponse
req?.payload = ["cognitoID" : cognitoID, "facebookID" : facebookID]
req?.functionName = getFunctionName(funcName: "MYFUNCNAME")
lambda.invoke(req!) { (response: AWSLambdaInvocationResponse?,error: Error?) in
print(error)
let payload = response?.payload
print(payload)
callback(true)
}
}
}
Обновление 2
Я обнаружил, что вызов метода обновления, как это:
credentialsProvider.credentials().continue({ (task: AWSTask!) -> Any? in
print(task.result)
})
Вызывает ошибку как это:
AWSiOSSDK v2.4.10 [Ошибка] AWSCredentialsProvider.m строка:577 | __44-[учетные данные AWSCognitoCredentialsProvider]_block_invoke.352 | Невозможно обновить. Ошибка [Ошибка домена =com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)" UserInfo={__type=ResourceNotFoundException, message=Identity 'us-east-1:0db18266-1baa-4c59-9110-f9041dc92ead' не найден.}]
Я считаю, что большая строка, которая выглядит как identitypoolID, на самом деле является идентификатором для данного пользователя, который у меня есть, поэтому cognito распространил идентификатор, но не может его запросить?
2 ответа
Думаю, мало что заставило это работать.
Я сделал правильный шаг, сделав свой собственный identityprovidermanager, и я думаю, что главным, что мешало мне выполнять лямбда-метод, был факт, что я использовал AWSLambda вместо AWSLambdaInvoker. После того, как я переключился, он начал делать ошибки, которые имели смысл.
Ошибка:
Логины не совпадают. Пожалуйста, укажите хотя бы один действительный логин для этой личности или пула
Это также может быть вызвано тем, что вы пытаетесь войти в систему как другой пользователь без выхода из системы, поэтому токен в словаре входа в систему сравнивается с identityId для другого идентификатора (и не совпадает). В этом случае SDK обычно восстанавливается путем повторной попытки, очистки и восстановления идентификатора, и затем он работает.
Но в вашем случае, так как вы создаете свой собственный словарь логинов, проблема, скорее всего, в том, что вы создали токен, который не совпадает. Вы можете проверить токены, используя https://jwt.io/. (хотя я признаю, что это работает для пулов пользователей Google и Cognito, но не для токенов Facebook (я не знаю, почему это так)),
Я думаю, что не совпадает означает, что identityId записывает другого уникального пользователя, чем указано в токене.
Вы уверены, что токен построен правильно?
Как вы упомянули... документацию... ну... я считаю, что документацию не стоит смотреть, поэтому я настроил свои проекты, чтобы я мог просматривать рабочий код и устанавливать точки останова.
Вот фрагмент кода из Facebook AWSSignInProvider от Mobile Hub Helper, который показывает, что они используют для получения токена (token.tokenstring).
- (AWSTask<NSString *> *)token {
FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
NSString *tokenString = token.tokenString;
NSDate *idTokenExpirationDate = token.expirationDate;
if (tokenString
// If the cached token expires within 10 min, tries refreshing a token.
&& [idTokenExpirationDate compare:[NSDate dateWithTimeIntervalSinceNow:AWSFacebookSignInProviderTokenRefreshBuffer]] == NSOrderedDescending) {
return [AWSTask taskWithResult:tokenString];
}
AWSTaskCompletionSource *taskCompletionSource = [AWSTaskCompletionSource taskCompletionSource];
[FBSDKLoginManager renewSystemCredentials:^(ACAccountCredentialRenewResult result, NSError *error) {
if (result == ACAccountCredentialRenewResultRenewed) {
FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
NSString *tokenString = token.tokenString;
taskCompletionSource.result = tokenString;
} else {
taskCompletionSource.error = error;
}
}];
return taskCompletionSource.task;
}
Также... Это стоит упомянуть. AWSIdentityManager и связанные с ним AWSSignInProviders - это удобная архитектура для входа в Facebook и Google. Даже если вы не используете остальную часть Mobile Hub Helper. Зачем заново изобретать колесо, они очень хорошо поработали над частью Identity aws-mobilehub-helper-ios
У меня есть версия этой библиотеки, размещенная на github, которая также добавляет AWSSignInProvider для пользовательских пулов Cognito. Для входа в систему-awsmhh требуются некоторые исправления в aws-mobilehub-helper-ios для использования пулов пользователей cognito. Они здесь https://github.com/BruceBuckland/aws-mobilehub-helper-ios (поэтому, если вы клонируете, выполняете клон --recursive, и вы будете настроены на отладку использование точек останова в библиотеке).