この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
API GatewayにはIAMでアクセスを制限する機能があります。
Serveress Frameworkで作成したAPIに、この機能によるアクセス制限を追加し、動作を確認するまでの手順について書いていきます。
手順について
LambdaとAPI Gatewayの構築
まずはServerless Frameworkでアクセス制限なしのLambdaとAPI Gatewayを作成します。Lambdaの言語はPython3系とします。
Serverless Frameworkをインストールします。今回は作業するローカルフォルダにインストールしました。
$ npm install serverless
バージョンを確認します。
$ ./node_modules/.bin/serverless --version
1.24.1
テンプレートを作成します。
$ ./node_modules/.bin/serverless create --template aws-python3
Lambdaのhandlerは自動生成されるものをそのまま使います。
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
# integration
"""
return {
"message": "Go Serverless v1.0! Your function executed successfully!",
"event": event
}
"""
serverless.ymlを編集し、リージョンとAPI Gatewayの設定を行います。
provider:
name: aws
runtime: python3.6
# you can overwrite defaults here
# stage: dev
region: ap-northeast-1 # リージョン指定
(中略)
functions:
hello:
handler: handler.hello
events: # ここから4行をAPI GatewayのGETメソッドを作成するために追加
- http:
path: hello
method: get
デプロイを行います。
$ ./node_modules/.bin/serverless deploy
動作確認を行います。
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .
{
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": {
"resource": "/hello",
"path": "/hello",
"httpMethod": "GET",
(以下略)
}
}
ここではまだIAMによるアクセス制御は行なっていないため、curlでGETをできています。
IAMでのアクセス制御を追加
serverless.ymlのAPI Gatewayの設定に、IAMでのアクセス制御を追加します。
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
authorizer: aws_iam # これを追加
デプロイを行います。
$ ./node_modules/.bin/serverless deploy
動作確認を行います。
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .
{
"message": "Missing Authentication Token"
}
先ほどと異なり、今度はcurlでのGETをできません。
署名バージョン 4を使用してAPIにアクセスする
上記のAPIにアクセスするには署名バージョン 4による署名が必要となります。今回はRubyのaws-sigv4と言うgemを使って実行してみました。
gemのインストールを行います。
Gemfile
# A sample Gemfile
source "https://rubygems.org"
# gem "rails"
gem 'aws-sigv4'
gem 'aws-sdk', '~> 2'
$ bundle install --path vendor/bundle
APIにアクセスするプログラムは以下のようになります。
main.rb
require 'aws-sigv4'
require 'open-uri'
require 'aws-sdk'
ec2 = Aws::EC2::Client.new
credentials = ec2.config[:credentials].credentials
signer = Aws::Sigv4::Signer.new(
service: 'execute-api',
region: 'ap-northeast-1',
access_key_id: credentials.access_key_id,
secret_access_key: credentials.secret_access_key,
)
url = signer.presign_url(
http_method: 'GET',
url: 'https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello',
)
open(url){|io|
puts io.read
}
以下のコマンドで実行します。
$ bundle exec ruby main.rb | jq .
{
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": {
"resource": "/hello",
"path": "/hello",
"httpMethod": "GET",
(以下略)
無事、APIにアクセスすることができました。