新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

ServerlessでAPI GatewayのオーソライザーをCORS対応する方法

本記事について

API GatewayのオーソライザーをCORSできるようにするための設定を、Serverless Framework上で行う方法について記載します。

詳しくは下記に記載されているものを、概要を加えて転記いたします。

解説

CORSについて

CORSなAPIにするには、APIのレスポンスヘッダーで「Access-Control-Allow-Headers」「Access-Control-Allow-Origin」を返す必要があります。

API Gatewayで[リソース]-[CORSの有効化]を行うと、API GatewayがCORSに必要なもろもろの設定を行ってくれます。

そのAPI GatewayのCORS設定を、Serverlessで行うには、公式サイトに記載のとおり、serverless.ymlで「cors: true」と記載することで行えます。

オーソライザーのCORSについて

APIでオーソライザーを使った場合のCORSの設定は、上記に加えもうひと手間必要になります。

認証に成功した場合は、本来のAPIが呼び出されるのでCORSのレスポンスの設定がされていて問題ありませんが、認証に失敗した場合は、APIは呼び出されず、オーソライザーからレスポンスが返されるため、別途オーソライザーからのエラー返答用にCORSの設定が必要になります。

この設定を行わないと、認証が失敗して応答があっても、クライアントでCORSエラーが発生して、認証エラーを検知することができなくなってしまいます。

手順(API Gatewayを使った場合)

「401 Unauthorized レスポンス」と「500 Authorizer Failure レスポンス」で下記のレスポンスヘッダーを返すようにします

  • 「Access-Control-Allow-Headers」:「'*'」
  • 「Access-Control-Allow-Origin」:「'*'」

設定は[ゲートウェイのレスポンス]で行います。

ServerlessでAPI GatewayのオーソライザーをCORS対応する方法

401・500の違い

公式ヘルプに記載のとおり、callback("Unauthorized")でエラーを返した場合は「401 Unauthorized」、「"Unauthorized"」以外でエラーを返した場合は「500 Internal Server Error レスポンス」になります。(本記事では両方を設定しています)

手順(Serverlessを使った場合)

設定は上記API Gatewayを使った場合と同じですが、API Gatewayを直接変更できないため、serverless.ymlの「resources」で、API Gateway設定を行います。

serverless.yml

resources:
  Resources:
    GatewayResponse401:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: UNAUTHORIZED
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        StatusCode: '401'
    GatewayResponse500:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: AUTHORIZER_FAILURE
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        StatusCode: '500'

以上で、認証失敗した場合でもレスポンスヘッダーが返されるようになり、オーソライザーを使ったAPIでもCORSが行えるようになります。

その他

ServerlessはCloudFormationでAWSのリソースを作成しており、ゲートウェイレスポンスの設定はCloudFormationのGatewayResponseの記述とほぼ同じです。