Hi everyone,
I’ve spent today implementing Cognito with AWS SAM and it took quite a while to work out what needed to be done – unfortunately there’s a lot of conflicting doco out there. Posting a sample template just in case it’s able to help anyone else out.
The first thing to do is to explicitly define you rest API. By default AWS SAM will generate one with a default logical id of ServerlessRestApi. You’ll need to override this:
Resources:
# See links for more info
# Referencing cognito authorizer: https://github.com/awslabs/serverless-application-model/issues/512#issuecomment-411284092
# Logical id is auto generated: https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
# Sample template.yml: https://github.com/awslabs/serverless-application-model/blob/release/v1.8.0/examples/2016-10-31/api_cognito_auth/template.yaml
MyCustomApi:
Type: "AWS::Serverless::Api"
Properties:
StageName: Prod
Auth: # We will eventually define other auth options here such as Usage Plans/Api Keys, AWS_IAM, and Resource Policies
DefaultAuthorizer: MyCustomCognitoAuthorizer
Authorizers:
MyCustomCognitoAuthorizer:
UserPoolArn: !GetAtt MyCustomCognitoUserPool.Arn # Can be a string, or array
# Identity: # Optional
# Header: ... # Optional; Default: Authorization
# ValidationExpression: ... # Optional; ensures the request header matches a pattern before checking in with the Authorizer endpoint; is there a default we can set for Cognito User Pools Auth?
You’ll also need to create a user pool and client:
# Creating a cognito user pool - https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/api_cognito_auth/template.yaml
MyCustomCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref CognitoUserPoolName
# LambdaConfig:
# PreSignUp: !GetAtt PreSignupLambdaFunction.Arn
Policies:
PasswordPolicy:
MinimumLength: 8
UsernameAttributes:
- email
Schema:
- AttributeDataType: String
Name: email
Required: false
MyCustomCognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId: !Ref MyCustomCognitoUserPool
ClientName: !Ref CognitoUserPoolClientName
GenerateSecret: false
You then add the api id and the auth attribute to each of your function properties. If you’ve used the default authorizer property when defining the associated api you can override it by using authorizer: none.
GetBreedFunction:
Type: AWS::Serverless::Function
Properties:
Handler: breed.getBreedHandler
Policies: arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
Runtime: nodejs8.10
Environment:
Variables:
TABLE_CAT_BREED: !Ref CatBreedTable
Events:
GetEvent:
Type: Api
Properties:
Path: /breed/{breedId}
Method: get
RestApiId: !Ref MyCustomCustomApi
Auth:
Authorizer: NONE
Hopefully that’s able to help you out. If you run into any trouble I found the following link pretty useful: https://github.com/awslabs/serverless-application-model/blob/release/v1.8.0/examples/2016-10-31/api_cognito_auth/template.yaml