如何在不达到每个 API 授权人限制的情况下在模板之间共享授权人
How to share an authorizer between templates without hitting limit of authorizers per API
我有十几个服务,每个服务都有自己的无服务器模板文件,在 API 网关上共享相同的根目录 API。
我的根 serverless.yml
文件定义了 API 和一个授权者:
...
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: ${self:service.name}-${self:provider.stage}
Description: Medimap API Gateway
GatewayResponseDefault4XX:
Type: "AWS::ApiGateway::GatewayResponse"
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
ResponseType: DEFAULT_4XX
RestApiId:
Ref: "ApiGatewayRestApi"
Outputs:
RestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:service.name}-${self:provider.stage}-RestApiId
RootResourceId:
Value:
Fn::GetAtt: ApiGatewayRestApi.RootResourceId
Export:
Name: ${self:service.name}-${self:provider.stage}-ApiGatewayRestApiRootResourceId
AuthenticationService:
Value:
Fn::GetAtt: AuthenticationServiceLambdaFunction.Arn
Export:
Name: ${self:service.name}-${self:provider.stage}-AuthenticationService
functions:
authenticationService:
handler: src/api/common/authenticationService.handler
environment:
JWT_SECRET: ${env:JWT_SECRET}
events:
- http:
path: authenticationService
method: post
cors: true
在我的每项服务的模板中,我都有如下代码:
provider:
...
apiGateway:
restApiId:
"Fn::ImportValue": "medimap-api-${self:provider.stage}-RestApiId"
restApiRootResourceId:
"Fn::ImportValue": "medimap-api-${self:provider.stage}-ApiGatewayRestApiRootResourceId"
custom:
authorizer:
name: example-authorizer
arn:
Fn::ImportValue: medimap-api-${self:provider.stage}-AuthenticationService
functions:
exampleFunction:
handler: src/api/example/exampleFunction.handler
events:
- http:
path: example/exampleFunction
method: get
cors: true
authorizer: ${self:custom.authorizer}
这工作正常,但是一旦我部署了 10 个服务,尝试使用相同的授权方部署第 11 个服务会出现以下错误:
Maximum number of Authorizers for this API has been reached. Please contact AWS if you need additional Authorizers.
现在,我可以联系 AWS 来提高限制,但由于它们在技术上都是相同的授权方,我觉得我应该有一种方法可以让它工作而无需为每个模板创建单独的授权方文件。
我尝试对所有授权人使用相同的授权人名称,但我最终收到错误:
Authorizer name must be unique. Authorizer example-authorizer already exists in this RestApi
有没有一种方法可以让我在同一个 API 上的所有服务中共享这个授权者,而不必为每个服务创建一个新命名的授权者,这样我就不会达到这个限制?
您可以共享授权方本身,而不是只共享每个(新)授权方的 Lambda 函数:
Api 网关堆栈:
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: ${self:service.name}-${self:provider.stage}
Description: Medimap API Gateway
GatewayResponseDefault4XX:
Type: "AWS::ApiGateway::GatewayResponse"
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
ResponseType: DEFAULT_4XX
RestApiId:
Ref: "ApiGatewayRestApi"
ApiGatewayAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerUri:
Fn::Join:
- ''
- - 'arn:'
- { Ref: AWS::Partition }
- ":apigateway:"
- { Ref: AWS::Region }
- ":lambda:path/2015-03-31/functions/"
- { 'Fn::GetAtt': [${self:service.name}-${self:provider.stage}-authenticationService, 'Arn'] }
- "/invocations"
IdentitySource: method.request.header.Authorization
Name: LambdaAuthorizer
RestApiId:
Ref: ApiGatewayRestApi
Type: TOKEN
Outputs:
RestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:service.name}-${self:provider.stage}-RestApiId
RootResourceId:
Value:
Fn::GetAtt: ApiGatewayRestApi.RootResourceId
Export:
Name: ${self:service.name}-${self:provider.stage}-ApiGatewayRestApiRootResourceId
AuthenticationService:
Value:
{ Ref: ApiGatewayAuthorizer }
Export:
Name: ${self:service.name}-${self:provider.stage}-AuthenticationService
functions:
authenticationService:
handler: src/api/common/authenticationService.handler
environment:
JWT_SECRET: ${env:JWT_SECRET}
events:
- http:
path: authenticationService
method: post
cors: true
在你的其他堆栈中:
functions:
exampleFunction:
handler: src/api/example/exampleFunction.handler
events:
- http:
path: example/exampleFunction
method: get
cors: true
authorizer:
type: TOKEN
authorizerId:
Fn::ImportValue: medimap-api-${self:provider.stage}-AuthenticationService
这是根据记忆+ CloudFormation文档完成的,所以请原谅任何编译错误...
来源:
https://serverless.com/framework/docs/providers/aws/events/apigateway#share-authorizer
我有十几个服务,每个服务都有自己的无服务器模板文件,在 API 网关上共享相同的根目录 API。
我的根 serverless.yml
文件定义了 API 和一个授权者:
...
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: ${self:service.name}-${self:provider.stage}
Description: Medimap API Gateway
GatewayResponseDefault4XX:
Type: "AWS::ApiGateway::GatewayResponse"
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
ResponseType: DEFAULT_4XX
RestApiId:
Ref: "ApiGatewayRestApi"
Outputs:
RestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:service.name}-${self:provider.stage}-RestApiId
RootResourceId:
Value:
Fn::GetAtt: ApiGatewayRestApi.RootResourceId
Export:
Name: ${self:service.name}-${self:provider.stage}-ApiGatewayRestApiRootResourceId
AuthenticationService:
Value:
Fn::GetAtt: AuthenticationServiceLambdaFunction.Arn
Export:
Name: ${self:service.name}-${self:provider.stage}-AuthenticationService
functions:
authenticationService:
handler: src/api/common/authenticationService.handler
environment:
JWT_SECRET: ${env:JWT_SECRET}
events:
- http:
path: authenticationService
method: post
cors: true
在我的每项服务的模板中,我都有如下代码:
provider:
...
apiGateway:
restApiId:
"Fn::ImportValue": "medimap-api-${self:provider.stage}-RestApiId"
restApiRootResourceId:
"Fn::ImportValue": "medimap-api-${self:provider.stage}-ApiGatewayRestApiRootResourceId"
custom:
authorizer:
name: example-authorizer
arn:
Fn::ImportValue: medimap-api-${self:provider.stage}-AuthenticationService
functions:
exampleFunction:
handler: src/api/example/exampleFunction.handler
events:
- http:
path: example/exampleFunction
method: get
cors: true
authorizer: ${self:custom.authorizer}
这工作正常,但是一旦我部署了 10 个服务,尝试使用相同的授权方部署第 11 个服务会出现以下错误:
Maximum number of Authorizers for this API has been reached. Please contact AWS if you need additional Authorizers.
现在,我可以联系 AWS 来提高限制,但由于它们在技术上都是相同的授权方,我觉得我应该有一种方法可以让它工作而无需为每个模板创建单独的授权方文件。
我尝试对所有授权人使用相同的授权人名称,但我最终收到错误:
Authorizer name must be unique. Authorizer example-authorizer already exists in this RestApi
有没有一种方法可以让我在同一个 API 上的所有服务中共享这个授权者,而不必为每个服务创建一个新命名的授权者,这样我就不会达到这个限制?
您可以共享授权方本身,而不是只共享每个(新)授权方的 Lambda 函数:
Api 网关堆栈:
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: ${self:service.name}-${self:provider.stage}
Description: Medimap API Gateway
GatewayResponseDefault4XX:
Type: "AWS::ApiGateway::GatewayResponse"
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
ResponseType: DEFAULT_4XX
RestApiId:
Ref: "ApiGatewayRestApi"
ApiGatewayAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerUri:
Fn::Join:
- ''
- - 'arn:'
- { Ref: AWS::Partition }
- ":apigateway:"
- { Ref: AWS::Region }
- ":lambda:path/2015-03-31/functions/"
- { 'Fn::GetAtt': [${self:service.name}-${self:provider.stage}-authenticationService, 'Arn'] }
- "/invocations"
IdentitySource: method.request.header.Authorization
Name: LambdaAuthorizer
RestApiId:
Ref: ApiGatewayRestApi
Type: TOKEN
Outputs:
RestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:service.name}-${self:provider.stage}-RestApiId
RootResourceId:
Value:
Fn::GetAtt: ApiGatewayRestApi.RootResourceId
Export:
Name: ${self:service.name}-${self:provider.stage}-ApiGatewayRestApiRootResourceId
AuthenticationService:
Value:
{ Ref: ApiGatewayAuthorizer }
Export:
Name: ${self:service.name}-${self:provider.stage}-AuthenticationService
functions:
authenticationService:
handler: src/api/common/authenticationService.handler
environment:
JWT_SECRET: ${env:JWT_SECRET}
events:
- http:
path: authenticationService
method: post
cors: true
在你的其他堆栈中:
functions:
exampleFunction:
handler: src/api/example/exampleFunction.handler
events:
- http:
path: example/exampleFunction
method: get
cors: true
authorizer:
type: TOKEN
authorizerId:
Fn::ImportValue: medimap-api-${self:provider.stage}-AuthenticationService
这是根据记忆+ CloudFormation文档完成的,所以请原谅任何编译错误...
来源:
https://serverless.com/framework/docs/providers/aws/events/apigateway#share-authorizer