AWS API Gateway を使用して API をデプロイしましたが、iOS デバイスからアクセスしようとしています。一部のエンドポイントは無許可のユーザーをサポートしており、アクセスに問題はありませんが、他のエンドポイントはサポートしておらず、クエリを実行できません。Web アプリケーション (または郵便配達員) を使用する場合に正常に動作する認証用の新しい Cognito ユーザー プール機能を使用します。
まず、一部のエンドポイントは保護されていますが (コンソールの次の図のように)、API をデプロイして iOS (Objective-C) 用の SDK を生成すると、README ファイルを読み取ることができます。承認は必要ありません。」
次に、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 を実装しました。
@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
適切なトークン (postman を使用してテスト済み) とユーザー ID を取得できました。
2016-12-27 12:43:35.760 AskHub[26625:10037234] AWSiOSSDK v2.4.11 [デバッグ] AWSURLResponseSerialization.m 行:63 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | 応答本文: {"IdentityId":"eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 2016-12-27 12:43:35.766 AskHub[26625:10037234] ID 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] 最初のリクエストを送信できませんでした: エラー Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ message = Unauthorized; }, HTTPHeaderFields={type = immutable dict, count = 9, entries => 3: Via = {contents = "XX 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 = "
ここで何か不足していますか?自動生成された SDK はユーザー プール認証をサポートしていますか?