iOS: AWSAPIGateWay - отсутствует проблема с аутентификацией - PullRequest
0 голосов
/ 30 октября 2018

Приложение не получает успешный вызов API после нескольких часов бездействия.

Шаги для воспроизведения поведения:

  1. Создание идентификатора Amazon Cognito.
  2. вызовы API.
  3. Поместите приложение в фоновом режиме.
  4. Обновить код через 8 часов. (initializeAmazonCongnitoProviderWithCompletionBlock, упомянутый ниже, вызывается первым, когда приложение выходит на передний план только через 8 часов) Отсутствующий токен авторизации будет отображаться, как показано на скриншоте. Какие сервисы AWS затронуты?

enter image description here

- (void)initializeAmazonCognitoProviderWithCompletionBlock:(void (^)(void))completion { 
    [[UIApplication sharedApplication].keyWindow setUserInteractionEnabled:FALSE];
    NSString* AWSCognitoPoolID = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"AWSCognitoID"];
    AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]  initWithRegionType:AMAZON_COGNITO_REGION identityPoolId:AWSCognitoPoolID];
    [credentialsProvider clearCredentials];
    AWSServiceConfiguration *configuration =[[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1  credentialsProvider:credentialsProvider];
    AWSServiceManager.defaultServiceManager.defaultServiceConfiguration =  configuration;

    [self getCognitoID:credentialsProvider CompletionBlock:^{
        [self expirationHandler:credentialsProvider CompletionBlock:^{
            dispatch_async(dispatch_get_main_queue(), ^{
              [[UIApplication sharedApplication].keyWindow setUserInteractionEnabled:TRUE];
            });
            completion();
        }];
    }]; 
}


- (void)expirationHandler:(AWSCognitoCredentialsProvider *)creds CompletionBlock: (void (^)(void))completion {
    [[creds credentials] continueWithBlock:^id(AWSTask *task) {
        if (task.error) {
            [self initializeAmazonCognitoProviderWithCompletionBlock:^{}];
        } else {
            AWSCredentials *cred = (AWSCredentials*) task.result;
            NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
            [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
            /* https://aws.amazon.com/premiumsupport/knowledge-center/security-token-expired/
             https://forums.aws.amazon.com/thread.jspa?threadID=166398
             We should fire timer before 5 minutes of expiration.
             NSString *expF = [dateFormat stringFromDate:cred.expiration];
             */
            [NSTimer scheduledTimerWithTimeInterval:cred.expiration.timeIntervalSinceNow -  300 target:self selector:@selector(initializeAmazonCognitoProviderWithCompletionBlock:) userInfo:nil repeats:NO];
            completion();
        }
        return nil;
    }];
}


- (void)getCognitoID:(AWSCognitoCredentialsProvider *)creds CompletionBlock: (void (^)(void))completion {
    [[creds getIdentityId] continueWithBlock:^id(AWSTask *task) {
        if (task.error) {
            NSLog(@"Error: %@", task.error);
            [self initializeAmazonCognitoProviderWithCompletionBlock:^{}];
        } else {
            NSString *cognitoId = task.result;
            NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
            if (![[standardDefaults valueForKey:@"UserCognitoID"] isEqualToString:cognitoId]) {
                [standardDefaults setObject:@"" forKey:BainPreferenceToken];
                [standardDefaults setInteger:0 forKey:@"registrationPostComplete"];
            }
            [standardDefaults setObject:cognitoId forKey:@"UserCognitoID"];
            [standardDefaults synchronize];
            completion();
        }
        return nil;
    }];
}

1 Ответ

0 голосов
/ 22 февраля 2019

AWSCognitoCredentialsProvider - это объект, который получает учетные данные из Amazon Cognito и предоставляет учетные данные для подписи запросов в AWS (например, для загрузки файла в S3).

AWSCognitoIdentityProvider объект в SDK предоставляет абстракцию для Amazon Cognito UserPools и помогает войти в систему пользователя и получить токены, которые подтверждают, что пользователь прошел аутентификацию.

Когда пользователь вошел в систему и AWSCognitoIdentityProvider получил токены из Amazon Cognito UserPools, токены можно объединить в AWSCognitoCredentialsProvider, чтобы получить AWSCredentials и Cognito Identity Id для этого аутентифицированного пользователя. Для этого необходимо указать токен на карте входа и передать карту входа на номер AWSCognitoCredentialsProvider.

Для этого вам нужно

1) создайте класс, который подтверждает протокол AWSIdentityProviderManager и реализует метод logins, который возвращает карту {providerLoginKey -> token}.

@interface AWSFederationManager : NSObject<AWSIdentityProviderManager>

@property (nonatomic, readonly, strong) AWSCognitoCredentialsProvider *credentialsProvider;

@end
@interface AWSFederationManager()

@property (nonatomic, readwrite, strong) AWSCognitoCredentialsProvider *credentialsProvider;

@end
@implementation AWSFederationManager

- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
        return [AWSTask taskWithResult:@{[<identityProviderName> : <token>}];
}

@end

2) Установите для делегата объекта AWSCognitoCredentialsProvider класс, созданный на шаге (1).

@implementation AWSFederationManager

- (instancetype) initialize {
    [self.credentialsProvider setIdentityProviderManagerOnce:self];
}

@end

Теперь, когда федерация будет успешной, вы сможете получить AWSCredentials и Cognito Identity Id.

Вы можете обратиться Source для справочной реализации.

...