APIキーが必要なAPI GatewayをAWS SAMとOpenAPIで作成してみました。
おすすめの方
- AWS SAMでAPI GatewayとLambdaを作成したい方
- AWS SAMでOpenAPIでAPI Gatewayを作成したい方
- AWS SAMでAPIキーが必要なAPI Gatewayを作成したい方
APIを作成する
sam init
sam init \
--runtime python3.11 \
--name api-gateway-need-api-key-sample \
--app-template hello-world \
--no-tracing \
--no-application-insights \
--structured-logging \
--package-type Zip
AWS SAMテンプレート
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ApiGateway-Need-API-Key-Sample
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
OpenApiVersion: 3.0.1
ApiKeySourceType: HEADER
Auth:
ApiKeyRequired: true
UsagePlan:
CreateUsagePlan: PER_API
UsagePlanName: Basic-usage-plan-of-AWS-SAM-api-gateway-plan
Quota:
Limit: 500
Period: MONTH
Throttle:
BurstLimit: 100
RateLimit: 50
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: s3://cm-fujii.genki-deploy/ApiGateway-Need-API-Key-Sample/api.yaml
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Timeout: 5
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
RestApiId: !Ref MyApi
HelloWorldFunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}
OpenAPI
api.yaml
openapi: 3.0.1
info:
title: ApiGateway-Need-API-Key-Sample
version: 1.0.0
paths:
/hello:
get:
tags:
- hello
responses:
200:
$ref: "#/components/responses/200"
403:
$ref: "#/components/responses/403"
500:
$ref: "#/components/responses/500"
security:
- apiKey: []
x-amazon-apigateway-integration:
type: aws_proxy
uri:
'Fn::Sub': >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations
httpMethod: POST
responses:
default:
statusCode: 200
passthroughBehavior: when_no_templates
contentHandling: CONVERT_TO_TEXT
components:
securitySchemes:
apiKey:
type: apiKey
name: x-api-key
in: header
responses:
200:
description: Success
403:
description: User or client is not authorized.
500:
description: Internal Server Error
Lambdaコード
app.py
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps(
{
"message": "hello world",
}
),
}
デプロイ
aws s3 cp \
api.yaml \
s3://cm-fujii.genki-deploy/ApiGateway-Need-API-Key-Sample/api.yaml
sam package \
--output-template-file packaged.yaml \
--s3-bucket cm-fujii.genki-deploy
sam deploy \
--template-file packaged.yaml \
--stack-name ApiGateway-Need-API-Key-Sample-Stack \
--s3-bucket cm-fujii.genki-deploy \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
APIの動作を確認する
「HEADER」を設定しているため、ヘッダーの「x-api-key」にAPIキーを設定します。
APIキーが無い場合は、403が返ってくる
$ curl -X GET -I https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello
HTTP/2 403
APIキーがある場合(違う)は、403が返ってくる
$ curl -X GET -I https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello \
-H "x-api-key: invalid-api-key"
HTTP/2 403
APIキーがある場合(合っている)は、200が返ってくる
$ curl -X GET -I https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello \
-H "x-api-key: valid-api-key"
HTTP/2 200