1

该应用程序在数小时不活动后未获得成功的 API 调用。

重现行为的步骤:

  1. 创建 Amazon Cognito ID。
  2. API 调用。
  3. 将应用程序置于后台。
  4. 8小时后刷新代码。(下面提到的initializeAmazonCongnitoProviderWithCompletionBlock 会在应用程序在8 小时后才进入前台时首先调用) Missing auth token 将如屏幕截图所示出现。哪些 AWS 服务受到影响?

在此处输入图像描述

- (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;
    }];
}
4

1 回答 1

0

AWSCognitoCredentialsProvider是一个对象,它从 Amazon Cognito 检索凭证并提供凭证以签署对 AWS 的请求(例如将文件上传到 S3)。

AWSCognitoIdentityProvider开发工具包中的对象为 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以获取参考实现。

于 2019-02-21T23:34:31.670 回答