API GatewayのLambdaオーソライザーで任意の403エラーメッセージをレスポンスする
- オーソライザーのレスポンスの
context
を使う。 - API Gatewayの『ゲートウェイのレスポンス』で、403エラー時にオーソライザーの
context
から取得した内容を返すようにする。
API GatewayのLambdaオーソライザーで Deny
を返すと、レスポンスはデフォルトで以下の通りになる。
これを自由な形で返せるようにする方法。
オーソライザーに context 設定
まず、Lambdaでオーソライザーを作ります。
API Gateway Lambda オーソライザーの使用 - Amazon API Gateway
↓このオーソライザーを使って認証を行うAPIが、あらかじめ存在すると仮定してくます。お試し用なので、リクエストヘッダの Authorization
値が aaa
なら Allow
としてます。
都合によりイベントペイロードがリクエストのオーソライザーですが、気にしないでください。トークンでも同様にできると思います。
大事なのはレスポンスの context.response
です。この記事では、認証エラー時にAPI Gatewayでこれをそのままレスポンスするように設定します。
本当にそのままレスポンスボディになるので、JSON.stringify()
してます。
ゲートウェイのレスポンス変更
次に、API Gatewayの設定を行います。
API Gatewayのコンソールの左メニューから『ゲートウェイのレスポンス』を開いて、『Access Denied [403]』を編集します。
『マッピングテンプレート』に $context.authorizer.response
と入力して保存します。
なお、画像ではレスポンスヘッダーが設定されてますが、これは内容とは関係ありません。エラー時もCORS有効化するために入れてあるだけです。
保存したら、忘れずデプロイしておきます。
結果
デプロイ完了したら、上記のオーソライザーが設定されたAPIを叩きます。(反映に数分かかるかも)
リクエストヘッダの Authorization
に aaa
以外を指定していれば、以下のレスポンスがステータスコード403で返ってきます。
ちゃんとオーソライザーの context.response
の通りになってるはずです。
備考
念のため書いておくと、response
というのは私が勝手につけたキーなので、マッピングテンプレートとLambdaの内容が対応してればどんな名前でも平気です。context.hoge
だったら、マッピングテンプレートは $context.authorizer.hoge
です。
それと、この方法はゲートウェイのレスポンスをいじってます。なので、もしオーソライザー以外で『Access Denied [403]』が出るルートが存在する場合、その時にレスポンスがカラになってしまうはずです。context.response
なんか設定されてないから。
少し触った限りでは無さそうでしたが、これで本当にどこにも弊害が出ないかは要検証。