使用无服务器,如何从资源中将 Lambda 函数的授权方设置为 Cognito 用户池?

Using Serverless, how do you set a Lambda function's authorizer to a Cognito User Pool from the Resources?

在我的 serverless.yml 中,我有一个 Lambda 函数,我想将它的授权方设置为我在下面的资源部分中声明的 Cognito 用户池。我见过将授权方设置为 aws_iam 的示例,但这似乎是错误的。任何帮助都会很棒 :)

我想我需要将授权方的 ARN 设置为池的 ARN,但我该如何获得它?或者这甚至是正确的?

这是您要找的吗? https://serverless.com/framework/docs/providers/aws/events/apigateway#http-endpoints-with-custom-authorizers

示例:

AFunctionName:
  handler: src/index.handler
  description: desc
  environment: ${file(environment.yml)}
  events:
    - http:
        method: any
        path: /api/{proxy+}
        authorizer:
          arn: arn:aws:cognito-idp:eu-west-1:123456:userpool/eu-west-1_123456

如另一个答案所述,对 ARN 进行硬编码是可行的。凭直觉,您可能会认为这样的方法可行:

    authorizer:
      arn: 
        Fn::GetAtt: [UserPool, Arn]

遗憾的是,事实并非如此。看起来 Serverless 将您的 arn 与几个正则表达式进行对比,以确定您是指向 lambda 还是用户池。这种方法似乎不能很好地与使用 RefFn::JoinFn::GetAtt

之类的方法一起使用

截至 Serverless 1.27.3 (which was released since this question was asked), there is a workaround of sorts 可用。

本质上,您在 resources 部分中声明了您的 Authorizer,而不是让 Serverless 自动神奇地为您创建它。然后,您使用 functions 部分中的新 authorizerId 密钥指向此授权方。一个最小的例子:

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]]} 

这不是很好,但比必须将用户池 ARN 硬编码到您的模板中要好。