我已经使用AWS API Gateway部署了一个API,并试图通过iOS设备访问它。有些终端支持未经授权的用户,我无法访问它们,但其他终端则不支持查询它们。我使用新的Cognito用户池功能进行身份验证,在使用Web应用程序(或邮递员)时可以正常工作。首先,即使一些端点受到保护(如下面的控制台图片所示),当我部署API并为iOS生成SDK(Objective-C)时,我可以在README文件中读取: “所有端点都不需要授权。”API网关为授权用户生成的iOS iOS(Objective-C)SDK with Cognito用户池
然后,当我运行从AWS文档下面的验证码,似乎一切就好了工作:
AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1 credentialsProvider:nil];
AWSCognitoIdentityUserPoolConfiguration *userPoolConfiguration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:ClientId clientSecret:nil poolId:UserPoolId];
[AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithConfiguration:serviceConfiguration userPoolConfiguration:userPoolConfiguration forKey:@"UserPool"];
AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:@"UserPool"];
AWSCognitoIdentityUser *user = [pool getUser];
[[user getSession:username password:password validationData:nil] continueWithBlock:^id(AWSTask<AWSCognitoIdentityUserSession *> *task) {
if (task.error) {
NSLog(@"Could not get user session. Error: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not get user session. Exception: %@", task.exception);
} else {
NSLog(@"Successfully retrieved user session data");
AWSCognitoIdentityUserSession *session = (AWSCognitoIdentityUserSession *) task.result;
NSMutableString *poolId = [[NSMutableString alloc] initWithString:@"cognito-idp.eu-west-1.amazonaws.com/"];
[poolId appendString:UserPoolId];
NSString *tokenStr = [session.idToken tokenString];
NSDictionary *tokens = [[NSDictionary alloc] initWithObjectsAndKeys:tokenStr, poolId, nil];
CognitoPoolIdentityProvider *idProvider = [[CognitoPoolIdentityProvider alloc] init];
[idProvider addTokens:tokens];
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionEUWest1 identityPoolId:IdentityPoolId identityProviderManager:idProvider];
[credentialsProvider clearKeychain];
[credentialsProvider clearCredentials];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1
credentialsProvider:credentialsProvider];
[[credentialsProvider getIdentityId] continueWithBlock:^id _Nullable(AWSTask<NSString *> * _Nonnull task) {
if (task.error) {
NSLog(@"Could not get identity id: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not get identity id: %@", task.exception);
} else {
NSLog(@"Identity id: %@", task.result);
}
return nil;
}];
}
return nil;
}];
我实现CognitoPoolIdentityProvider为this post规定。
@interface CognitoPoolIdentityProvider()
@property (strong, nonatomic) NSDictionary *tokens;
@end
@implementation CognitoPoolIdentityProvider
- (AWSTask<NSDictionary *> *)logins {
return [AWSTask taskWithResult:self.tokens];
}
- (void)addTokens:(NSDictionary *)tokens {
self.tokens = tokens;
}
@end
我设法得到一个正确的令牌(测试使用邮递员)和用户ID:
2016-12-27 12:43:35.760 AskHub[26625:10037234] AWSiOSSDK v2.4.11 [Debug] AWSURLResponseSerialization.m line:63 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: {"IdentityId":"eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 2016-12-27 12:43:35.766 AskHub[26625:10037234] Identity id: eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
然而,当我运行下面的代码打一个受保护的端点,CloudFront的认为,我未认证。
APIHealthClient *apiClient = [APIHealthClient defaultClient];
APIAskHubRequest *initReq = [[APIAskHubRequest alloc] init];
initReq.message = @"FIN";
NSLog(@"Sending initial request");
[[apiClient webhooksAskhubPost:initReq] continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(@"Could not send initial request: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not send initial request: %@", task.exception);
} else {
NSLog(@"Successfully sent initial request");
}
return nil;
}];
的回复:
2016-12-27 12:56:25.247 AskHub[26784:10046562] Could not send initial request: Error Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ message = Unauthorized; }, HTTPHeaderFields={type = immutable dict, count = 9, entries => 3 : Via = {contents = "X.X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)"} 4 : x-amzn-ErrorType = {contents = "UnauthorizedException"} 5 : Content-Type = {contents = "application/json"} 6 : Content-Length = {contents = "27"} 7 : Connection = {contents = "keep-alive"} 8 : x-amzn-RequestId = {contents = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 9 : Date = {contents = "Tue, 27 Dec 2016 11:56:25 GMT"} 10 : X-Cache = {contents = "Error from cloudfront"} 11 : X-Amz-Cf-Id = {contents = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"} } }
我在这里失去了一些东西?自动生成的SDK是否支持用户池身份验证?
我有同样的问题,你有...我有一个通过我的cognito用户池授权的api。当我通过邮递员调用这个api并在用户池中传入一个来自用户的有效的id令牌的“Authorization”头时,它就可以工作。但是,当我尝试通过生成的api ios sdk通过ios调用相同的api时,我得到相同的错误。我的猜测是,ios中还有一件事尚未安装?如果我找到它,我会继续沿着它回到这里。 –