Question:
In my serverless.yml, I have a Lambda function and I want to set it’s authorizer to a Cognito User Pool that I have declared in the Resources section down below. I’ve seen examples where the authorizer is set to aws_iam
but that seems wrong. Any help would be amazing 🙂
I’m thinking I need to set the authorizer’s ARN to the Pool’s ARN, but how do I get that? Or is that even correct?
Answer:
As noted in another answer, hard coding the ARN works. So intuitively, you might think something like this would work:
1 2 3 4 |
authorizer: arn: Fn::GetAtt: [UserPool, Arn] |
Sadly, it does not. It looks like Serverless bumps your arn
up against a couple of regular expressions to determine whether you’re pointing at a lambda or a user pool. This approach doesn’t seem to play nicely with approaches using things like Ref
, Fn::Join
, or Fn::GetAtt
As of Serverless 1.27.3 (which was released since this question was asked), there is a workaround of sorts available.
Essentially you declare your Authorizer in your resources
section, instead of letting Serverless auto-magically create it for you. Then you use the new authorizerId
key in your functions
section to point at this authorizer. A minimal example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
service: sls-cognitotest provider: name: aws runtime: nodejs6.10 functions: hello: handler: handler.hello events: - http: method: any path: /api/{proxy+} integration: lambda authorizer: type: COGNITO_USER_POOLS authorizerId: { Ref: MyApiGatewayAuthorizer } resources: Resources: CognitoUserPoolGeneral: Type: AWS::Cognito::UserPool Properties: UserPoolName: general MyApiGatewayAuthorizer: Type: AWS::ApiGateway::Authorizer Properties: AuthorizerResultTtlInSeconds: 10 IdentitySource: method.request.header.Authorization Name: MyCognitoAuthorizer RestApiId: Ref: ApiGatewayRestApi Type: COGNITO_USER_POOLS ProviderARNs: - {"Fn::Join": ["", ["arn:aws:cognito-idp:", {Ref: "AWS::Region"}, ":", {Ref: "AWS::AccountId"}, ":userpool/", Ref: CognitoUserPoolGeneral]]} |
It isn’t great, but it’s better than having to hard code the user pool ARN into your template.