【问题标题】:AWS API Gateway unreliability in refreshAWS API Gateway 刷新不可靠
【发布时间】:2016-02-26 08:15:37
【问题描述】:

我使用 API 网关已经很长时间了,我只是稍微更改了 api 以允许其他功能。我进入 api gateway 并测试了该功能以确保它有效。然后我在我的 iPhone 上试了一下,效果也不错。之后,我开始随机收到 {errorMessage: "Task timed out after 3.00 seconds"} 的重复实例。我不明白为什么一个简单的登录方法(API 网关中的方法)会超时,特别是因为我在 iPhone(以前工作时)和直接使用 api 网关控制台上测试了输入。

评论:我没有使用生成的 sdk 或 AWSAPIGatewayClient。我只是发出一个http请求。

http 请求登录

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSMutableDictionary *post = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                      [defaults objectForKey:@"username"], @"username",
                      [defaults objectForKey:@"password"], @"password",
                      nil];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:post options:0 error:&error];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"someLoginEndpoint"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSDictionary *newJSON = [NSJSONSerialization JSONObjectWithData:data
                                                            options:0
                                                              error:&error];
    if(!newJSON || [newJSON objectForKey:@"errorMessage"]){
        NSLog(@"%@",newJSON);
        callBack(false);
        NSLog(@"DID NOT AUTHENTICATE");
    }else{
        NSLog(@"%@",newJSON);
        [defaults setValue:[newJSON objectForKey:@"Token"] forKey:@"Token"];
        [defaults setValue:[newJSON objectForKey:@"IdentityId"] forKey:@"IdentityId"];
        [self authenticateUser:^(BOOL call){
            callBack(call);
        }];
    }
}] resume];

刷新方法

- (AWSTask *)refresh {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![self authenticatedWithProvider]) {
    return [super getIdentityId];
}else{
    NSDictionary *post = [[NSDictionary alloc] initWithObjectsAndKeys:
                          [defaults objectForKey:@"username"], @"username",
                          [defaults objectForKey:@"password"], @"password",
                          nil];
    NSError *error;
    NSData *postData = [NSJSONSerialization dataWithJSONObject:post options:0 error:&error];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"someLoginEndpoint"]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:postData];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    __block BOOL isLogged = false;

    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *newJSON = [NSJSONSerialization JSONObjectWithData:data
                                                                options:0
                                                                  error:&error];
        isLogged = true;
        if(!newJSON){
            NSLog(@"DID NOT AUTHENTICATE");
        }else{
            NSLog(@"The IdentityID in the refresh method: %@",[newJSON objectForKey:@"IdentityId" ]);
            NSLog(@"The token in the refresh method: %@",[newJSON objectForKey:@"Token" ]);
        self.identityId = [newJSON objectForKey:@"IdentityId" ];
        self.token = [newJSON objectForKey:@"Token" ];
        }

    }] resume];

    return [super getIdentityId];

}
return [super getIdentityId];
}

验证用户身份

 //BusytimeAuthenticated
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id<AWSCognitoIdentityProvider> identityProvider = [[BusytimeAuthenticated alloc] initWithRegionType:AWSRegionUSEast1
                                                                                         identityId:nil
                                                                                     identityPoolId:@"somePoolID"
                                                                            logins:@{@"cognito-identity.amazonaws.com": [defaults objectForKey:@"Token"]}
                                                                                       providerName:@"cognito-identity.amazonaws.com"
                                                   ];

credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                               identityProvider:identityProvider
                                                                  unauthRoleArn:nil
                                                                    authRoleArn:nil];
configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
                                            credentialsProvider:self.credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
[[credentialsProvider refresh] continueWithBlock:^id(AWSTask *task){
    callBack(true);
    return nil;
}];

}

错误 无法刷新。错误是 [Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)" UserInfo={message=Invalid login token.无法传入 Cognito 令牌。,__type=NotAuthorizedException}]

我的基本问题是,为什么这个操作如此不可靠?它有时可以登录我的用户,然后当我使用刷新方法时,我传递了相同的凭据,但并行请求导致第二个请求失败。

【问题讨论】:

  • 您使用的是 Lambda 集成吗? Lambda 冷启动可能会导致您的 API Gateway 调用超时,您可能需要优化您的 Lambda 以避免超时。此外,您只包括了您的刷新方法。 Cognito 错误似乎表明您对身份提供者进行编码的方式存在问题。您可能希望使用完整的身份提供者实施来更新您的问题。
  • 等一下,我会更新我的问题。但是是的,我正在使用 lambda 集成,我会考虑对其进行优化。

标签: objective-c amazon-web-services amazon-cognito aws-api-gateway


【解决方案1】:

关于超时:

如 cmets 中所述,Lambda 冷启动可能会导致您的 API Gateway 调用超时,您可能需要优化您的 Lambda 以避免超时。

关于刷新错误:

您在登录映射中使用 cognito-identity.amazonaws.com,但使用 IdentityProvider 模式进行刷新。这就是第一次身份验证成功但尝试刷新失败的原因。刷新中的逻辑永远不会触发。

我建议您查看我们的end-to-end sample,了解处理开发人员身份验证的建议流程。

如果您想在登录映射中继续使用 cognito-identity.amazonaws.com,那么您的令牌刷新实际上需要在身份外部处理/credentials 提供者,类似于您处理 Facebook 令牌的方式。

【讨论】:

  • 如何优化我的 lambda 方法?我应该只是增加超时时间,还是有什么特定的东西可以改善冷启动时间?
  • 我想知道是否可以对“关于刷新错误”部分进行一些说明。我完全不知道你认为我应该如何处理这个问题。示例应用程序变得非常混乱,因为它没有像刷新方法中的其他部分那样评论它正在做什么。
  • 前段时间我也遇到了堆栈溢出问题,我遇到了开发人员身份验证的几个问题,我被告知要从“MyProviderName”切换到“cognito-identity.amazonaws.com”。
  • 这是我被建议从“MyProviderName”切换的问题:stackoverflow.com/questions/33228309/…
  • 如果您不使用 AWSCognitoIdentityProvider 模式,则使用 cognito-identity.amazonaws.com 有效。您可能想查看this forum post,它应该有望阐明这种模式的预期流程。
猜你喜欢
  • 1970-01-01
  • 2022-08-02
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 2017-03-30
  • 1970-01-01
  • 2017-12-30
相关资源
最近更新 更多