【CDK/Python】Lambda認証付きのHTTPタイプのAPIを作る
以前RestAPI
で同じことをしていますが、今度は後発のHttpAPI
で作ってみます。
では 作っていきましょう👻
プロジェクトを用意する
雛形を用意
$ mkdir cdk-http-api-lambda && cd $_
$ cdk init --language python
$ rm setup.py source.bat
$ mkdir src tests
依存パッケージ
aws-cdk.core==1.124.0
aws_cdk.aws-lambda==1.124.0
aws_cdk.aws_lambda_python==1.124.0
aws-cdk.aws_apigatewayv2==1.124.0
aws-cdk.aws_apigatewayv2_integrations==1.124.0
aws_cdk.aws_apigatewayv2_authorizers==1.124.0
ResAPIはaws_apigatewayv
のモジュールなので、完全に総入れ替えです
インストール
$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
Stackを用意する
aws_apigatewayv2
のパッケージを使いますが、ほとんどRestAPI
の場合と同じです。
その中で唯一大きな違いは、認証Lambdaの方式です。
RestAPI
側はトークン認証だったのですが、HTTP API
側はシンプル(type?)を使うことができるのでそちらを使います。(今回やらないですが、今まで通りの認証のやり方も可能)
from aws_cdk import core as cdk
from aws_cdk.aws_apigatewayv2 import CorsHttpMethod, HttpApi, HttpMethod
from aws_cdk.aws_apigatewayv2_authorizers import HttpLambdaAuthorizer, HttpLambdaResponseType
from aws_cdk.aws_apigatewayv2_integrations import LambdaProxyIntegration
from aws_cdk.aws_lambda import Runtime
from aws_cdk.aws_lambda_python import PythonFunction
APP_NAME = "CdkHttpApiLambda"
class CdkHttpApiLambdaStack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
common_lambda_param = {"runtime": Runtime.PYTHON_3_9}
auth_lambda = PythonFunction(self, f"{APP_NAME}AuthLambda", entry="src/authorizer", **common_lambda_param)
app_lambda = PythonFunction(self, f"{APP_NAME}AppLambda", entry="src/app", **common_lambda_param)
authorizer = HttpLambdaAuthorizer(
authorizer_name="hogehoge_authorizer",
identity_source=["$request.header.HogeAuthorization"],
response_types=[HttpLambdaResponseType.SIMPLE], # シンプルタイプを指定
handler=auth_lambda,
)
lambda_integration = LambdaProxyIntegration(handler=app_lambda)
http_api = HttpApi(
self,
f"{APP_NAME}HttpApi",
cors_preflight={
"allow_origins": ["*"],
"allow_headers": ["*"],
"allow_methods": [CorsHttpMethod.ANY],
},
)
http_api.add_routes(
path="/",
methods=[HttpMethod.ANY],
integration=lambda_integration,
authorizer=authorizer,
)
余談でPython3.9がcdkでも使えるようになったので、使ってみました(笑)
アプリを書く
認証用のLambdaです。
トークン認証の場合とレスポンスが大きく変わり、必須パラメーターはisAuthorized
だけです。
この値に対して{ true | false }
で認証成功/失敗を返すことができます!
お手軽ですねー
認証以外に後ろのLambdaに渡したいパラメータがあればcontext
に入れればOKです。
後方のLambdaには、eventからこんな感じで受け取れます。
// eventの中身
{
...
"requestContext": {
...
"authorizer": {
"lambda": {
"hogeKey": 12345
}
},
...
}
というわけで、具体的な実装は下記。
def handler(event, context):
res = {"isAuthorized": False}
if event["headers"]["hogeauthorization"] == "hogehoge":
res.update({"isAuthorized": True, "context": {"hogeKey": 12345}})
return res
動きはRequestのheaderを見てhogeauthorization
がhogehoge
という値だったら許可します!
次にapp側です。
def handler(event, context):
return {"statusCode": "200", "body": "Hello World !!"}
はい。説明不要ですね(笑)
デプロイ
下記のコマンドでデプロイ!
$ cdk deploy
動作確認
AWS環境で
# 失敗
$ curl https://767mhcfq8c.execute-api.ap-northeast-1.amazonaws.com
{"message":"Unauthorized"}
$ curl https://767mhcfq8c.execute-api.ap-northeast-1.amazonaws.com -H 'HogeAuthorization: a'
> {"message":"Forbidden"}
# 成功
$ curl https://767mhcfq8c.execute-api.ap-northeast-1.amazonaws.com -H 'HogeAuthorization: hogehoge'
Hello World !!
local環境で(おまけ)
実は今年の4月末くらいに CDKがSAMで動かせるというとんでも機能が出てます!!
ということでlocalでも動かしてみます。
導入方法はこちらを参考にしてください!
local環境でAPI起動!!
$ sam-beta-cdk local start-api --project-type CDK
エンドポイントを叩く
$ curl http://127.0.0.1:3000/
SHello World !!
はい、認証Lambda貫通でapi叩けます(汗)
SAMは認証はしてくれないのですねー。詳細は下記を御覧ください
https://github.com/aws/aws-sam-cli/issues/137
以上ですー