Serverless-application-model: SAM template create OPTIONS method in api gateway

Created on 18 Dec 2018  路  13Comments  路  Source: aws/serverless-application-model

Hi, why with the following yaml file cloudfomation create a method relative to my desidered api (/hello)?
I noticed that by removing 'globals' section (the CORS options) the OPTIONS method is no longer crated but the cors is now ncessary for me.

``` AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
Api:
# enable CORS; to make more specific, change the origin wildcard
# to a particular domain name, e.g. "'www.example.com'"
Cors:
AllowMethods: "''"
AllowHeaders: "'
'"
AllowOrigin: "'*'"

Parameters:
CognitoUserPoolName:
Type: String
Default: AppUsers

Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: CognitoAuthorizer
Authorizers:
CognitoAuthorizer:
UserPoolArn: arn:aws:cognito-idp:xxx:userpool/xxx

HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs8.10
Events:
HelloGfmiApi:
Type: Api
Properties:
Path: /hello
Method: GET
RestApiId: !Ref MyApi
```

Following a screen of ip gateway status

image

Any suggest?

Thanks

areserverless-api typquestion

Most helpful comment

@jimmy-ml @nicklit there is a new feature in SAM that you can allow OPTIONS to don't ask for Authorization! It's a flag called AddDefaultAuthorizerToCorsPreflight, you can check it and you avoid to specify for each method the Auth

AddDefaultAuthorizerToCorsPreflight: False

Anyway, Thanks for the help!

All 13 comments

CORS operates via specially crafted OPTIONS requests. That mock endpoint is what produces the CORS responses.

I'm afraid there's nothing to suggest. If your API requires CORS (and it probably does), it needs a way to respond to the OPTIONS verb.

This is expected behavior for CORS support.

Testing with template from the first comment SAM/Cloudformation creates GET and OPTIONS which is perfectly OK.
I am curious if it is OK that both methods are guarded by Cognito authorizer?
This way it would be required from browser to send headers as if it was sending real GET which is a) not happening b) probably also not according to w3c specs.
Not even "withCredentials" is option here as browser won't copy headers to preflight even with this.

Same issue here. The OPTION method is secured by Cognito also and I'm pretty sure it shouldn't be that way.
@pokusak Did you find a way of fixing it?

@leantorres73 @Nik1990
I solved it like this:

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        # DefaultAuthorizer: CognitoAuthorizer
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: arn:aws:cognito-idp:xxx:userpool/xxx

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      Events:
        HelloGfmiApi:
          Type: Api
          Properties:
            Path: /hello
            Method: GET
            RestApiId: !Ref MyApi
            Auth:
                Authorizer: NediCognitoAuthorizer

@jimmy-ml @nicklit there is a new feature in SAM that you can allow OPTIONS to don't ask for Authorization! It's a flag called AddDefaultAuthorizerToCorsPreflight, you can check it and you avoid to specify for each method the Auth

AddDefaultAuthorizerToCorsPreflight: False

Anyway, Thanks for the help!

AddDefaultAuthorizerToCorsPreflight : False is not working.
Is there any additional configuration we have to do ?
Please suggest.
Thanks

@dilippatidar123 Are you using the latest version? This is a new feature, it was release one month ago in version v1.13.0.

Check at the end of this issue https://github.com/awslabs/serverless-application-model/issues/717

@dilippatidar123 So my question is, it fails in the deploy saying the property does not exist or everything is created correctly but CORS is not working?

@leantorres73 Its not giving any property or deployment error. But its still taking the default authorizer for options method.
Currently we are using following code for option method.

Events: 
        ProxyApiRoot1: 
          Type: Api 
          Properties: 
            RestApiId: !Ref ApiGatewayApi 
            Path: /{proxy+} 
            Method: ANY
        ProxyApiRoot2:
           Type: Api
           Properties:
             RestApiId: !Ref ApiGatewayApi
             Path: /{proxy+}
             Method: OPTIONS
             Auth:
               Authorizer: NONE
Auth:
        DefaultAuthorizer: Authorizer
        Authorizers:
          Authorizer:
            FunctionPayloadType: REQUEST
            FunctionArn: 'Authorizer arn'
            FunctionInvokeRole: "Role arn'
            Identity:
              Headers:
                 - Cookie
              ReauthorizeEvery: 300 # seconds

After adding AddDefaultAuthorizerToCorsPreflight: False flag,I believe we don't need to add explicit code in events for options method.

Please correct me if I am wrong.

Thanks

That's correct, you don't need to include ProxyApiRoot2 at all. If you're using SAM, you will have something like this:

 Api:
    Cors:
      AllowHeaders: "'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization'" 
      AllowOrigin: "'*'"
    Auth:
      DefaultAuthorizer: CognitoAuthorizer
      Authorizers:
        CognitoAuthorizer:
          UserPoolArn: yourUserPool
      AddDefaultAuthorizerToCorsPreflight: False

@leantorres73 Thanks Its working.

@leantorres73 Somehow this syntax of enabling CORS fixed my issue, thank you.

Was this page helpful?
0 / 5 - 0 ratings