使用无服务器,如何从资源中将 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,但我该如何获得它?或者这甚至是正确的?
示例:
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 还是用户池。这种方法似乎不能很好地与使用 Ref
、Fn::Join
或 Fn::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 硬编码到您的模板中要好。
在我的 serverless.yml 中,我有一个 Lambda 函数,我想将它的授权方设置为我在下面的资源部分中声明的 Cognito 用户池。我见过将授权方设置为 aws_iam
的示例,但这似乎是错误的。任何帮助都会很棒 :)
我想我需要将授权方的 ARN 设置为池的 ARN,但我该如何获得它?或者这甚至是正确的?
示例:
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 还是用户池。这种方法似乎不能很好地与使用 Ref
、Fn::Join
或 Fn::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 硬编码到您的模板中要好。