Claudia.jsはAWS上でAPI GatewayとAWS Lambdaによるサーバレスアーキテクチャを簡単に実現できるNode.js製のフレームワークです。
この際、Facebook, Google, Twitterの用な外部の認証プロバイダから取得したOAuth Access TokenをAPI Gatewayのレイヤーで検証して問題なければ裏のLambdaに投げたいケースが多いと思います。
Claudia.jsを使えばこのような処理が10分もあれば実装できます。
[関連記事]
-
- Claudia.jsを使わない方法で面倒なのでオススメしません。
-
- このように取得したFacebookのAccess Tokenをチェックしたい場合です。
準備
1. Claudia.jsをインストールします。
npm install -g claudia
2. プロジェクトを作成します。
mkdir [Proj Name] && cd [Proj Name]
npm init
npm install --save claudia-api-builder
npm install --save aws-sdk
npm install --save axios
実装
以下のようなフロントエンドアプリを実装してみます。エラー処理や詳細は割愛します。また、Hello World的なものはCloudia.jsのTutorialをみた方が手っ取り早いです。
- フロントエンドアプリがSNSの認証認可APIからOAuthのアクセストークンを取得する。(略)
- フロントエンドアプリがアクセストークンを付与してAWS API Gatewayにリクエストを投げる。(略)
- AWS API GatewayがSNSの認証認可APIを用いてアクセストークンを検証する。
- AWS API GatewayがFaaSの関数を呼び出す。
- AWS Lambdaの関数がAWS DynamoDBのテーブルからデータを取得してフロントに返す。
1. カスタム認証の作成
1. カスタム認証用のLambda関数を作成します。
authorizer.js
を作成します。Access Token検証APIを呼び出して有効な場合にAPI実行権限を付与しています。
var axios = require('axios');
//API実行ポリシーの生成
var generatePolicy = function(authToken, methodArn, context) {
var awsInfo = methodArn.split(':');
var region = awsInfo[3];
var accountId = awsInfo[4];
var apiInfo = awsInfo[5].split('/');
var restApiId = apiInfo[0];
var stage = apiInfo[1];
var method = apiInfo[2];
//アクセスさせたいリソース
var resource = 'arn:aws:execute-api:' + region + ':' + accountId + ':' + restApiId + '/' + stage +'/' + method + '/*';
return {
'principalId': authToken.split('-')[0],
'policyDocument': {
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Action': ['execute-api:Invoke'],
'Resource': [resource]
}]
}
};
};
var url = "Access TokenのValidateを行うAPIのURL";
//Tokenの検証とポリシーの付与
exports.auth = function auth(event, context, cb) {
axios.get(url, {
params: {
access_token: event.authorizationToken //HTTP headerのAuthorizationキーの値
}
}).then(function (res) {
var is_valid = true|false; //Tokenの有効性を検証して結果を格納
if (is_valid) {
cb(null, generatePolicy(event.authorizationToken, event.methodArn));
} else {
cb("Invalid Access Token");
}
});
};
2. デプロイ
claudia
コマンドでカスタム認証用のLambda関数をAWSにデプロイします。
claudia create --name custom-authorizer --region us-east-1 --handler authorizer.auth --config claudia-auth.json
-
--name
: AWS Lambda上の関数名 -
--region
: AWSのリージョン名 -
--handler
: カスタム認証の関数名 -
--config
: Claudia.js用の設定ファイル名(自動作成されるので任意)
{
"lambda": {
"role": "custom-authorizer-executor",
"name": "custom-authorizer",
"region": "us-east-1"
}
}
2. APIとLambda関数の作成
1. APIとLambda関数を作成します。
app.js
という名前にします。
var ApiBuilder = require('claudia-api-builder');
var api = new ApiBuilder();
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
api.registerAuthorizer('apiGatewayAuthorizer', {
lambdaName: 'custom-authorizer', //AWS Labmda上のカスタム認証の名前
headerName: 'Authorization' //Tokenを格納するHTTP headerのKey名
});
api.get('/news', function (req) {
return dynamodb.get({
TableName:'news',
Key:{ "id": req.headers.id }
}).promise().then(function(res) {
return res.Item;
});
},{
customAuthorizer: 'apiGatewayAuthorizer'
});
module.exports = api;
2. デプロイ
claudia
コマンドでAWSにデプロイします。設定ファイルclaudia.json
が自動で作られます。
claudia create --region us-east-1 --api-module app
{
"lambda": {
"role": "myproj-executor",
"name": "myproj-proj",
"region": "us-east-1"
},
"api": {
"id": "[PID]",
"module": "app",
"url": "[エンドポイントのベースURL]"
}
}
3. AWS上の設定
-
AWS DynamoDBのテーブル作成
news
テーブルを作成するaws dynamodb create-table --table-name news --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
id
キーで検索できるようにレコードを追加。aws dynamodb put-item --table-name news --item '{"id":{"S":"id001"}, "content":{"S":"News content 001"}}' aws dynamodb put-item --table-name news --item '{"id":{"S":"id002"}, "content":{"S":"News content 002"}}' :
-
AWS Lambdaのrole設定
- IAM > Roles > [作成したRole名]
- Attach Pollicy >
AmazonDynamoDBFullAccess
- 強すぎるので実際は適当なPolicyを作成
4. API実行
-
PostmanなどでHTTPヘッダの
Authorization
キーにAccess Tokenを、id
キーに存在するidを付与して投げます。Claudia.jsでAPIを作成した際にはCORSはデフォルトでONになっていますが制限することもできます。
Controlling Cross-Origin Resource Sharing headers
5. アップデート
-
スクリプトを修正します。
-
claudia
コマンドを実行します。claudia update --config claudia-auth.json claudia update --config claudia.json
まとめ
Claudia.jsを利用すれば、外部の認証認可APIを用いたサーバレスアーキテクチャを簡単に実装できます。
より詳細な記事はこちら
以上