Amazon API Gateway の API を Cognito で認証して呼び出す
API を IAM で認証する
Amazon API Gateway (以下 API Gateway) で作成した API は、誰でも呼び出せるように公開する他に、2つの認証方法が用意されています。
この2つの方法のうち、今回は IAM で認証する方法を試してみたいと思います。
API Gateway にはモバイルアプリ向けの SDK を生成する機能がある点から、モバイルアプリを主なターゲットにしているように思えます。そこで、Amazon Cognito (以下 Cognito) を利用した認証方式を通して API Gateway で作成した API を呼び出してみたいと思います。
先日まで生成した SDK の認証周りでエラーが発生し Cognito (IAM Role) を利用した呼び出しが行えないことがありましたが、生成される SDK がアップデートされたため、現在は呼び出せるようになりました。
API の作成
今回は OpenWeatherMap の Weather API をラップした API を作り、この API のクライアントを作ります。API の作成手順、および SDK の生成手順は以下のブログにまとめてありますので、こちらの手順通りに作成してください。
- Amazon API Gateway を使って AWS 以外のサービスの API をラップする | Developers.IO
- Amazon API Gateway の API のクライアント SDK を生成して iOS アプリから呼び出す | Developers.IO
- Amazon API Gateway の API のクライアント SDK を生成して Android アプリから呼び出す | Developers.IO
API の Authorization type の変更
次に、作成した API の Method の Authorization type を変更します。まず Method Execution 画面を表示し、Method Request をクリックします。
Authorization type は NONE
または AWS_IAM
のいずれかを選択できます。今回は AWS_IAM
を設定しましょう。また ARN は後で使うのでメモっておきましょう。
ここまで終わったら、デプロイを行っておきましょう。なお SDK が生成済みの場合は再度生成する必要はありません。
Cognito の Identity Pool の作成
次に Cognito の Identity Pool を作成します。Cognito の Management Console を開き「Create Identity Pool」をクリックします(Identity Pool を作成したことがない場合は「Get Started」)。
Identity pool name は APIGatewayApp
としました。また、今回は認証プロバイダを用いた認証を行いませんので、Unauthenticated identities の Enable access to unauthenticated identities にチェックを入れておきましょう。
次に IAM Role の作成画面が表示されるので、ここで新規作成するポリシーを調整しましょう。2番目の Role Summary の View Policy Document をクリックし、続けて Edit をクリックします。
IAM Policy は、次のようにしましょう。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "execute-api:Invoke" ], "Resource": [ "arn:aws:execute-api:us-east-1:xxxxxxxxxxxx:xxxxxxxxxx/*/GET/weather" ] } ] }
Action
には execute-api:Invoke
、Resource
に Method Request に表示されている ARN を貼り付けましょう。
これで Identity Pool の完成です。サンプルコードの中に書かれている Identity Pool ID をメモしておいてください。
iOS アプリから呼び出す
それでは、iOS アプリを実装しましょう。ここで使う iOS アプリは以下のブログで作成したものを使います。記事を参考に、作成しておいてください。
上記の処理に加えて、Cognito の認証情報を組み込む処理が必要になります。これは以前までと全く同じ方法ですので、新しく何か必要になるわけではありません。
// Cognito認証 AWSCognitoCredentialsProvider *provider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:@"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]; AWSServiceConfiguration *configutation = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:provider]; [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configutation; CLIWeatherAPIClient *client = [CLIWeatherAPIClient defaultClient]; [[client weatherGet:@"London"] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) { if (task.error) { NSLog(@"Error: %@", task.error); } else if (task.exception) { NSLog(@"Exception: %@", task.exception); } else { CLIWeather *weather = task.result; CLIWeather_weather_item *item = weather.weather.firstObject; NSString *message = [NSString stringWithFormat:@"Weather: %@", item.main]; [[[UIAlertView alloc] initWithTitle:@"Get response" message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Close", nil] show]; } return nil; }];
これで、認証付きで呼び出せました。
Android アプリから呼び出す
今度は、Android アプリを実装しましょう。ここで使う Android アプリは以下のブログで作成したものを使います。記事を参考に、作成しておいてください。
上記の処理に加えて、Cognito の認証情報を組み込む処理が必要になります。これは以前までと全く同じ方法ですので、新しく何か必要になるわけではありません。
void invoke() { // Cognitoの認証 CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider( self, // Context "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // Identity Pool ID Regions.US_EAST_1 // Region ); WeatherAPIClient client = new ApiClientFactory() .credentialsProvider(credentialsProvider) .build(WeatherAPIClient.class); Weather weather = client.weatherGet("Toyko"); WeatherWeatherItem item = weather.getWeather().get(0); final String message = "Weather : " + item.getMain(); runOnUiThread(new Runnable() { @Override public void run() { new AlertDialog.Builder(self) .setTitle("Weather") .setMessage(message) .setPositiveButton(android.R.string.ok, null) .create() .show(); } }); }
Android でも認証付きで呼び出せました。
まとめ
API Gateway の API は IAM を使って細かく制御できます。例えば、未ログインユーザーはこの API の GET だけ、ログインユーザーは POST もできるようにするなどといったポリシーも実現可能です。モバイルアプリでも API Gateway をぜひ使っていきましょう!