是否可以从无服务器AWS API中的其他lambda函数调用lambda函数?

问题描述

我正在使用AWS SAM模板和ASP.Net Core创建无服务器API。 我想知道是否可以从多个Lambda函数调用一个通用的Lambda函数吗?

我有2个用于用户身份验证的API。

  1. /用户/身份验证
  2. / admin / authenticate

现在,当用户调用这些API端点时,我想调用一个通用的lambda函数,该函数如下所示:

public AuthResponse Authenticate(AuthInfo info,int role);

我得到一个基于哪个API端点被调用用户角色。例如,如果调用/user/authetication,则调用role=1,否则调用role=0。 然后,我希望Authenticate()lambda基于AuthInfo + Role执行用户身份验证。

我要这样做是因为我所有的用户都存储在同一个表中,并且我想交叉验证用户是否具有访问该功能的正确角色。

我还将共享用于上述API的serverless.template的一部分。

/ admin / authenticate

"Handler": "Server::API.Admin::Authenticate","Description" : "Allows admin to authenticate","Runtime": "dotnetcore2.1","CodeUri": "","MemorySize": 256,"Timeout" : 300,"Role": {"Fn::GetAtt" : [ "LambdaExecutionRole","Arn"]},"FunctionName" : "AdminAuthenticate","Events": 
        {
          "PutResource": 
          {
            "Type": "Api","Properties": 
            {
              "Path": "/v1/admin/authenticate","Method": "POST"
            }
          }
        }
      }
    }

/用户/身份验证

"Handler": "Server::API.User::Authenticate","Description" : "Allows user to authenticate","FunctionName" : "UserAuthenticate","Properties": 
            {
              "Path": "/v1/user/authenticate","Method": "GET"
            }
          }
        }
      }
    }

正如您在上面看到的那样,分别创建了两个lambda函数AdminAuthenticateUserAuthentication。我希望这些lambda函数共享通用代码

有人知道怎么做吗?

感谢和问候。

解决方法

我可以考虑两种选择来实现您的目标。在第一个选项中,您使用多个Lambda函数,每个端点一个,都指向同一代码库。在第二个选项中,您有一个Lambda函数可以处理所有身份验证需求。

单个代码库,多个功能

在这种情况下,您可以使用2个函数定义模板文件,但是使用CodeUri属性指向相同的代码库。

{
    "AWSTemplateFormatVersion": "2010-09-09","Transform": "AWS::Serverless-2016-10-31","Resources": {
        "AdminFunction": {
            "Type": "AWS::Serverless::Function","Properties": {
                "Handler": "Server::API.Admin::Authenticate","Description": "Allows admin to authenticate","Runtime": "dotnetcore2.1","CodeUri": "./codebase_path/","MemorySize": 256,"Timeout": 300,"FunctionName": "AdminAuthenticate","Events": {
                    "PutResource": {
                        "Type": "Api","Properties": {
                            "Path": "/v1/admin/authenticate","Method": "POST"
                        }
                    }
                }
            }
        },"UserFunction": {
            "Type": "AWS::Serverless::Function","Properties": {
                "Handler": "Server::API.User::Authenticate","Description": "Allows user to authenticate","FunctionName": "UserAuthenticate","Properties": {
                            "Path": "/v1/user/authenticate","Method": "POST"
                        }
                    }
                }
            }
        }
    }
}

单个代码库,单个功能

在这种情况下,您将在API网关上公开2个端点,但是它们将被定向到函数上的同一处理程序。因此,您将需要在代码上编写一些逻辑以正确处理登录。传递给您Lambda函数的event对象将在path属性中拥有有关原始URL的信息(reference-即使适用于Lambda代理,仍然适用)。

在这种情况下,模板文件类似于(请注意,我将Admin / User术语替换为“ Any”,因为它将处理任何形式的身份验证):

{
    "AWSTemplateFormatVersion": "2010-09-09","Resources": {
        "AnyFunction": {
            "Type": "AWS::Serverless::Function","Properties": {
                "Handler": "Server::API.Any::Authenticate","Description": "Allows any to authenticate","CodeUri": "./hello_world/","Events": {
                    "UserEndpoint": {
                        "Type": "Api","Method": "POST"
                        }
                    },"AdminEndpoint": {
                        "Type": "Api","Method": "POST"
                        }
                    }
                }
            }
        }
    }
}
,

您可以使用所选语言的aws sdk通过任何lambda函数调用 lambda函数,并在其中定义了调用函数。 供参考,这里是link to boto3 invoke definition

您使用通用代码库进行身份验证的方法不正确。

如果您需要lambda函数来检查或认证特定请求,则可以为此设置自定义授权者,以您的说法,我可以说是共享lambda代码或首先调用它,然后调用您为特定端点设置的lambda,并可以根据需要传递自定义数据。

Lambda授权者(或作为自定义授权者)是一种 API网关功能,该功能使用Lambda函数来控制对API的访问。

enter image description here

如果这仍然不能解决您的问题,并且您想要通用的代码库,则可以将多达api端点的指向同一lambda函数。 然后,您必须在代码库中处理 event ['resources'] 。 这不是推荐的方法,但是您可以使用它。

您可以推荐aws samples来设置自定义授权者,否则documentation足以消除您的所有疑问。