API GatewayとLambdaを使う際に、FacebookやTwitterなどのOAuth Acesss Tokenをチェックしたいケースがあるかと思います。
この記事では、API GatewayのAuthorizer機能を用いてAccess Tokenを検証する流れを簡略化してまとめてみます。
前提
- AWSのブラウザコンソールを利用
- LambdaではNode.jsを利用
- 各OAuthプロバイダ固有処理やエラー処理は割愛
処理の流れ
クライアント, SNS, API Gatewayを含めた全体の流れは以下のようなものです。
クライアントアプリ(iOS/Android/SPAなど)
--[認証認可情報]--> SNSのAccess Token発行API
--[Access Token]--> クライアントアプリ
--[Access Token]--> API GatewayのMethod Request
--[Access Token]--> Authorizer (=Lambdaの関数)
--[Access Token]--> SNSのAccess Token検証API
--[検証結果]--> Authorizer
----> API GatewayのIntegration Request
----> バックエンド(LambdaやHTTPリクエストなど)
----> API GatewayのIntegration Response
----> API GatewayのMethod Response
----> クライアントアプリ
1. [API Gateway] APIの作成
説明を簡単にするためにMock APIを作成します。
-
新たなAPIを作成します。
- APIs > Create APIをクリック
-
作成したAPIにHTTP Methodを追加します。
- API > Actions > Create Method > GET > Mock
- 簡略化のためここではとりあえずルートパスの/を利用します。
- API > Actions > Create Method > GET > Mock
-
Mock用のレスポンスJSONを作成します。
- Integration Response > 200 > Body Mapping Templates > application/json > レスポンス用のJSONを入力
-
APIをデプロイします。
- API > Actions > Deploy API > Stage作成("prod"とする)
-
APIを呼び出します。
- 表示されたURLをcurlなどから叩いて入力したJSONが帰ってくるか確認します
2. [Lambda] Custom Authorizer用のFunction作成
API GatewayのAuthorizer機能で利用するAccess Token検証用関数をLambdaで作成します。
-
Create Lambda Function > Configure function (他のタブは無視)
-
Name : authFunction (任意)
-
Runtime : Node.js 4.3 (例はNode.jsにしますが何でもOK)
-
Lambda function code:
exports.handler = function(event, context) { //API Gatewayから渡されたAccess Token var token = event.authorizationToken; // ToDo : Access Tokenの検証処理 // SNSなどのAccess Token検証APIを叩いて結果を取得します。 // ※検証結果は authorized か unauthorized と簡略化します。 // ※通常非同期処理のはずですが簡略化します。 // var authResult = 検証結果 'authorized' or 'unauthorized' switch (authResult) { case 'authorized': context.succeed(generatePolicy('user', 'Allow', event.methodArn)); break; case 'unauthorized': context.succeed(generatePolicy('user', 'Deny', event.methodArn)); break; default: context.fail("Error"); } }; var generatePolicy = function(principalId, effect, resource) { return { principalId: principalId, policyDocument: { Version: '2012-10-17', Statement: [{ Action: 'execute-api:Invoke', Effect: effect, Resource: resource }] } }; }
-
Handler : index.handler
-
Role : Create new role
-
Role name : "simple_microservice" (任意)
-
Policy templates : Simple Microservice Template (適当な物を設定)
-
-
(任意)テスト用のレスポンスを作成します。
- Actions > Configure Test Event > 以下を貼付
{ "authorizationToken": "authorized" }
-
(任意)テストを実行します。
- Testをクリックして以下が帰ってくることを確認
{ "principalId": "user", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow" } ] } }
3. [API Gateway] Custom Authorizerの割当
API GatewayのAuthorizerにLambdaで作成したAccess Token検証用関数を割当てます。
-
先ほど作成したAPIを選択します。
-
Custom Authorizerを作成します。
- Authorizers > New Custom Authorizer
- Lambda region : authFunctionを作成したリージョンを指定
- Lambda function :
authFunction
- Authorizer name :
myAuth
(任意) - Identity token source :
method.request.header.Authorization
- HTTPリクエストのヘッダのAuthorizationキーの値をLambdaの
authFunction
のauthorizationTokenに渡します。
- HTTPリクエストのヘッダのAuthorizationキーの値をLambdaの
- Authorizers > New Custom Authorizer
-
ダイアログが表示されるのでOKをクリックします。
- API GatewayのroleにauthFunctionを実行する権限が自動追加されます。
-
(任意)テストを実行します。
-
画面右下の
Test your authorizer
をクリック -
Identity tokenに
authorized
などを入力してTestをクリック{ "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:ap-northeast-1:xxxxx:yyyyyy/null/GET/" } ] }
-
-
Lambda側で作成したAccess Token検証用の関数を割り当てます
- API > Resources > Method > Method Request > Authorization
- 2で設定した
myAuth
を選択します。
- 2で設定した
- API > Resources > Method > Method Request > Authorization
-
APIをデプロイします。
-
APIを実行して結果を確認します。
- HTTP Headerに
Authorization
キーと値をセットしてAPIを叩きます。
- HTTP Headerに
以上