自由帳

@_nibral の技術ブログ

AWS SAMでDefaultAuthorizerを設定するとCORSに失敗する

-------- 2019/10/17追記 --------

AWS SAMのアップデートでこの問題は解消した。

nibral.hateblo.jp

-------- 追記ここまで --------

問題

AWS SAMのAWS::Serverless::Apiでは、AuthプロパティのDefaultAuthorizerをセットすることですべてのエンドポイントに対してオーソライザーを設定できる。

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: !Ref CognitoUserPoolArn

また、Corsプロパティをセットすることですべてのエンドポイントに対してCORSを有効にできる。

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      Cors:
        AllowOrigin: "'*'"

ところが、これら2つのプロパティを同時にセットすると、CORSのプリフライトリクエスト(OPTIONS)に対してもオーソライザーが有効になってしまい、CORSに失敗する。(401 Unauthorizedが返る)

解決策

AWS::Serverless::ApiのDefaultAuthorizerを削除し、AWS::Serverless::FunctionのEventsに対して個別にAuthプロパティを設定する。

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      Auth:
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: !Ref CognitoUserPoolArn
      Cors:
        AllowOrigin: "'*'"

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      CodeUri: src/
      Events:
        GetIndex:
          Type: Api
          Properties:
            Path: /
            Method: get
            Auth:
              Authorizer: CognitoAuthorizer

github.com

Authorizerの設定を忘れると誰でもアクセス可能になってしまうので好ましい解決策とは言えないが、現時点ではこうするしかないようだ。

プリフライトリクエストに対してDefaultAuthorizerを適用するかどうかのプロパティ(AddDefaultAuthorizerToCorsPreflight)を追加するプルリクエストを作成した人がいたようだが、ユニットテストをパスできないとかで取り下げられてしまっている。

github.com