AWS SAMでDefaultAuthorizerを設定するとCORSに失敗する
-------- 2019/10/17追記 --------
AWS SAMのアップデートでこの問題は解消した。
-------- 追記ここまで --------
問題
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
Authorizerの設定を忘れると誰でもアクセス可能になってしまうので好ましい解決策とは言えないが、現時点ではこうするしかないようだ。
プリフライトリクエストに対してDefaultAuthorizerを適用するかどうかのプロパティ(AddDefaultAuthorizerToCorsPreflight)を追加するプルリクエストを作成した人がいたようだが、ユニットテストをパスできないとかで取り下げられてしまっている。