使用 Lambda 触发器自定义用户池工作流
Amazon Cognito 使用 Amazon Lambda 函数来修改用户群体的身份验证行为。您可以将您的用户群体配置为在用户首次注册之前、完成身份验证之后以及两者之间的几个阶段自动调用 Lambda 函数。您的函数可以修改身份验证流程的默认行为,发出 API 请求以修改您的用户群体或其他 Amazon 资源,以及与外部系统通信。您的 Lambda 函数中的代码是您自己的。Amazon Cognito 会将事件数据发送到您的函数,等待函数处理数据,而且在大多数情况下,预计会出现一个响应事件,该事件反映您要对会话进行的任何更改。
在请求和响应事件系统中,您可以引入自己的身份验证质询、在用户群体与其他身份存储之间迁移用户、自定义消息以及修改 JSON Web 令牌 (JWT)。
Lambda 触发器可以自定义用户在您的用户群体中启动操作后 Amazon Cognito 向用户提供的响应。例如,您可以阻止原本会成功的用户登录。他们还可以对您的 Amazon 环境、外部 API、数据库或身份存储执行运行时操作。例如,迁移用户触发器可以将外部操作与 Amazon Cognito 中的更改相结合:您可以在外部目录中查找用户信息,然后根据该外部信息设置新用户的属性。
当您为用户群体分配 Lambda 触发器时,Amazon Cognito 会中断其原定设置流程,以从您的函数请求信息。Amazon Cognito 生成 JSON 事件并将其传递给您的函数。该事件包含有关您的用户旨在创建用户账户、登录、重置密码或更新属性的请求的信息。然后,您的函数有机会采取行动,或者将事件原封不动地发回。
下表总结了使用 Lambda 触发器自定义用户池操作的一些方法:
用户池流 | 操作 | 描述 |
---|---|---|
自定义身份验证流程 |
定义身份验证质询 | 确定自定义身份验证流中的下一个挑战 |
创建身份验证质询 | 在自定义身份验证流中创建挑战 | |
验证身份验证质询响应 | 确定响应在自定义身份验证流中是正确的 | |
身份验证事件 | 身份验证前 Lambda 触发器 | 自定义验证以接受或拒绝登录请求 |
身份验证后 Lambda 触发器 | 记录自定义分析的事件 | |
令牌生成前 Lambda 触发器 | 增加或隐藏令牌声明 | |
注册 | 注册前 Lambda 触发器 | 执行接受或拒绝注册请求的自定义验证 |
确认后 Lambda 触发器 | 为自定义分析添加自定义欢迎消息或事件日志记录 | |
迁移用户 Lambda 触发器 | 将用户从现有用户目录迁移到用户池 | |
消息 | 自定义消息 Lambda 触发器 | 执行消息的高级自定义和本地化 |
令牌创建 | 令牌生成前 Lambda 触发器 | 添加或删除 ID 令牌中的属性 |
电子邮件和 SMS 第三方提供商 | 自定义发件人 Lambda 触发器 | 使用第三方提供商发送 SMS 和电子邮件 |
主题
重要注意事项
在为 Lambda 函数准备用户群体时,请考虑以下各项:
-
Amazon Cognito 发送到 Lambda 触发器的事件可能会随着新功能推出而发生变化。响应和请求元素在 JSON 层次结构中的位置可能改变,或者可能会添加元素名称。在 Lambda 函数中,您预期会收到本指南中介绍的输入元素键值对,但是更严格的输入验证可能会导致您的函数失败。
-
您可以从 Amazon Cognito 发送到某些触发器的多个事件版本中选择一个。某些版本可能需要您接受对 Amazon Cognito 定价的更改。有关定价的更多信息,请参阅 Amazon Cognito 定价
。要在 令牌生成前 Lambda 触发器 中自定义访问令牌,您必须使用高级安全功能配置用户群体,并更新 Lambda 触发器配置以使用事件版本 2。 -
Amazon Cognito 会同步调用 Lambda 函数,但 自定义发件人 Lambda 触发器 除外。Amazon Cognito 调用您的 Lambda 函数时,函数必须在 5 秒内响应。如果并非如此,并且可以重试调用,则 Amazon Cognito 会重试调用。3 次尝试失败后,该函数将超时。您无法更改此 5 秒钟超时值。有关更多信息,请参阅《Amazon Lambda 开发人员指南》中的 Lambda 编程模型。
Amazon Cognito 不会重试返回调用错误且 HTTP 状态代码为 500-599 的函数调用。这些代码表示配置问题导致 Lambda 无法启动该函数。有关更多信息,请参阅 Amazon Lambda 中的错误处理和自动重试。
-
您无法在 Lambda 触发器配置中声明函数版本。默认情况下,Amazon Cognito 用户群体会调用您的函数的最新版本。但是,您可以将函数版本与别名相关联,并将触发器
LambdaArn
设置为 CreateUserPool 或 UpdateUserPool API 请求中的别名 ARN。此选项在Amazon Web Services Management Console中不可用。要了解有关别名的更多信息,请参阅《Amazon Lambda 开发人员指南》中的 Lambda 函数别名。 -
如果您删除某个 Lambda 触发器,必须更新用户池中的相应触发器。例如,如果您删除身份验证后触发器,则必须在相应用户池中将 Post authentication(身份验证后)触发器设置为 none(无)。
-
如果您的 Lambda 函数没有向 Amazon Cognito 返回请求和响应参数,或者返回错误,则身份验证事件将无法成功。您可以在函数中返回错误,以阻止用户注册、身份验证、令牌生成或其身份验证流程中任何其他调用 Lambda 触发器的阶段。
Amazon Cognito 托管 UI 将返回 Lambda 触发器生成的错误作为登录提示上方的错误文本。Amazon Cognito 用户群体 API 以
格式返回触发器错误。最佳做法是,仅在 Lambda 函数中生成您希望用户看到的错误。使用输出方法(如[trigger]
failed with error[error text from response]
print()
)将任何敏感或调试信息记录到 CloudWatch Logs 中。有关示例,请参阅注册前示例:如果用户名少于五个字符,则拒绝注册。 -
您可以将另一个 Amazon Web Services 账户中的 Lambda 函数添加为用户群体的触发器。您必须使用 CreateUserPool 和 UpdateUserPool API 操作或它们在 Amazon CloudFormation 和 Amazon CLI 中的等效操作添加跨账户触发器。您无法在 Amazon Web Services Management Console中添加跨账户函数。
-
当您在 Amazon Cognito 控制台中添加 Lambda 触发器时,Amazon Cognito 会向您的函数添加一个基于资源的策略,允许您的用户群体调用该函数。当您在 Amazon Cognito 控制台之外创建 Lambda 触发器(包括跨账户函数)时,您必须向 Lambda 函数的基于资源的策略添加权限。您添加的权限必须允许 Amazon Cognito 代表您的用户群体调用函数。您可以从 Lambda 控制台添加权限或者使用 Lambda AddPermission API 操作。
Lambda 基于资源的策略示例
以下 Lambda 基于资源的策略示例授予 Amazon Cognito 有限调用 Lambda 函数的能力。Amazon Cognito 只能在代表
aws:SourceArn
中的用户池和aws:SourceAccount
条件中的账户时才能调用函数。{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "lambda-allow-cognito", "Effect": "Allow", "Principal": { "Service": "cognito-idp.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "
<your Lambda function ARN>
", "Condition": { "StringEquals": { "AWS:SourceAccount": "<your account number>
" }, "ArnLike": { "AWS:SourceArn": "<your user pool ARN>
" } } } ] }
添加用户池 Lambda 触发器
使用控制台添加用户池 Lambda 触发器
-
使用 Lambda 控制台
创建 Lambda 函数。有关 Lambda 函数的更多信息,请参阅《Amazon Lambda 开发人员指南》https://docs.amazonaws.cn/lambda/latest/dg/。 -
转到 Amazon Cognito 控制台
,然后选择 User Pools(用户池)。 -
从列表中选择一个现有用户池,或创建一个用户池。
-
选择 User pool properties(用户池属性)选项卡,并找到 Lambda triggers(Lambda 触发器)。
-
选择 Add a Lambda trigger(添加 Lambda 触发器)。
-
基于您希望自定义的身份验证阶段,选择 Lambda 触发器 Category(类别)。
-
选择 Assign Lambda function(分配 Lambda 函数),然后在同一个 Amazon Web Services 区域 中选择一个函数作为您的用户池。
注意
如果您的 Amazon Identity and Access Management (IAM) 凭证有权更新 Lambda 函数,Amazon Cognito 将添加基于 Lambda 资源的策略。通过此政策,Amazon Cognito 可以调用您选择的函数。如果登录凭证没有足够的 IAM 权限,则必须单独更新基于资源的策略。有关更多信息,请参阅 重要注意事项。
-
选择 Save changes(保存更改)。
-
您可以在 Lambda 控制台中使用 CloudWatch 记录您的 Lambda 函数。有关更多信息,请参阅访问适用于 Lambda 的 CloudWatch Logs。
用户池 Lambda 触发器事件
Amazon Cognito 将事件信息传递给 Lambda 函数。随后,Lambda 函数将相同事件对象随同响应中的任何更改返回给 Amazon Cognito。此事件显示了 Lambda 触发器通用参数:
用户池 Lambda 触发器通用参数
- version
-
您的 Lambda 函数的版本号。
- triggerSource
-
触发 Lambda 函数的事件的名称。有关每个 triggerSource 的说明,请参阅将 Lambda 触发器连接到用户群体功能操作。
- region
-
Amazon Web Services 区域,作为
AWSRegion
实例。 - userPoolId
-
用户池的 ID。
- userName
-
当前用户的用户名。
- callerContext
-
有关请求和代码环境的元数据。它包含 awsSdkVersion 和 clientId 字段。
- awsSdkVersion
-
生成请求的 Amazon SDK 版本。
- clientId
-
用户群体应用程序客户端的 ID。
- request
-
您的用户的 API 请求的详细信息。它包括以下字段以及触发器特定的任何请求参数。例如,Amazon Cognito 发送到预身份验证触发器的事件也将包含一个
userNotFound
参数。当您的用户尝试使用未注册的用户名登录时,您可以处理此参数的值以执行自定义操作。- userAttributes
-
用户属性名称和值的一个或多个键值对,例如
"email": "john@example.com"
。
- 响应
-
此参数在原始请求中不包含任何信息。Lambda 函数必须将整个事件返回给 Amazon Cognito,并将任何返回参数添加到
response
。要查看您的函数可以包含哪些返回参数,请参阅要使用的触发器的文档。
将 API 操作连接到 Lambda 触发器
以下部分介绍 Amazon Cognito 从您的用户群体中的活动调用的 Lambda 触发器。
当您的应用程序通过 Amazon Cognito 用户群体 API、托管 UI 或用户群体端点登录用户时,Amazon Cognito 会根据会话上下文调用您的 Lambda 函数。有关 Amazon Cognito 用户群体 API 和用户群体端点的更多信息,请参阅使用用户池 API 和授权服务器。以下各节中的表格描述了导致 Amazon Cognito 调用函数的事件,以及 Amazon Cognito 在请求中包含的 triggerSource
字符串。
Amazon Cognito API 中的 Lambda 触发器
下表描述了 Lambda 触发器的源字符串,当您的应用程序创建、登录或更新本地用户时,Amazon Cognito 可以调用这些触发器。
API 操作 | Lambda 触发器 | 触发器源 |
---|---|---|
注册前 |
|
|
令牌生成前 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
注册前 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
确认后 |
|
|
身份验证前 |
|
|
定义身份验证质询 |
|
|
创建身份验证质询 |
|
|
令牌生成前 |
|
|
迁移用户 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
迁移用户 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
确认后 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
托管 UI 中的 Amazon Cognito 本地用户的 Lambda 触发器
下表描述了 Lambda 触发器的源字符串,当本地用户使用托管 UI 登录您的用户群体时,Amazon Cognito 可以调用这些触发器。
托管 UI URI | Lambda 触发器 | 触发器源 |
---|---|---|
/signup |
注册前 |
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
/confirmuser |
确认后 |
|
/login |
身份验证前 |
|
定义身份验证质询 |
|
|
创建身份验证质询 |
|
|
令牌生成前 |
|
|
迁移用户 |
|
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
/forgotpassword |
迁移用户 |
|
自定义消息 |
|
|
自定义电子邮件发件人 |
|
|
自定义 SMS 发送人 |
|
|
/confirmforgotpassword |
确认后 |
|
针对联合身份用户的 Lambda 触发器
您可以使用以下 Lambda 触发器,为使用联合身份提供商登录的用户自定义用户池工作流。
注意
联合用户可以使用 Amazon Cognito 托管 UI 进行登录,也可以生成对 对端点授权 的请求,以静默方式将他们重新导向到其身份提供者登录页面。您无法使用 Amazon Cognito 用户群体 API 登录联合用户。
登录事件 | Lambda 触发器 | 触发器源 |
---|---|---|
首次登录 | 注册前 |
|
确认后 |
|
|
令牌生成前 |
|
|
后续登录 | 身份验证前 |
|
身份验证后 |
|
|
令牌生成前 |
|
联合身份登录不会在您的用户池中调用任何 自定义身份验证质询 Lambda 触发器、迁移用户 Lambda 触发器、自定义消息 Lambda 触发器 或者自定义发件人 Lambda 触发器。
将 Lambda 触发器连接到用户群体功能操作
每个 Lambda 触发器都在您的用户群体中发挥功能作用。例如,触发器可以修改您的注册流程,或添加自定义身份验证质询。Amazon Cognito 发送到 Lambda 函数的事件可以反映构成该函数角色的多个操作之一。例如,当您的用户注册时以及当您创建用户时,Amazon Cognito 会调用预注册触发器。同一功能角色的每个不同案例都有其自身的 triggerSource
值。您的 Lambda 函数可以根据调用该函数的操作以不同的方式处理传入事件。
当事件对应于触发器源时,Amazon Cognito 还会调用所有分配的函数。例如,当用户登录到您分配了迁移用户和预身份验证触发器的用户群体时,他们会同时激活这两个触发器。
触发器 | triggerSource 值 | 事件 |
---|---|---|
注册前 | PreSignUp_SignUp |
注册前。 |
注册前 | PreSignUp_AdminCreateUser |
在管理员创建新用户时做好注册准备。 |
注册前 | PreSignUp_ExternalProvider |
适用于外部身份提供商的注册前。 |
确认后 | PostConfirmation_ConfirmSignUp |
注册后确认。 |
确认后 | PostConfirmation_ConfirmForgotPassword |
忘记密码后确认。 |
身份验证前 | PreAuthentication_Authentication |
身份验证前。 |
身份验证后 | PostAuthentication_Authentication |
身份验证后。 |
触发器 | triggerSource 值 | 事件 |
---|---|---|
定义身份验证质询 | DefineAuthChallenge_Authentication |
定义身份验证质询。 |
创建身份验证质询 | CreateAuthChallenge_Authentication |
创建身份验证质询。 |
验证身份验证质询 | VerifyAuthChallengeResponse_Authentication |
验证身份验证质询响应。 |
触发器 | triggerSource 值 | 事件 |
---|---|---|
令牌生成前 | TokenGeneration_HostedAuth |
Amazon Cognito 从您托管的 UI 登录页面对用户进行身份验证。 |
令牌生成前 | TokenGeneration_Authentication |
用户身份验证流程完成。 |
令牌生成前 | TokenGeneration_NewPasswordChallenge |
管理员创建用户。当用户必须更改临时密码时,Amazon Cognito 调用此项。 |
令牌生成前 | TokenGeneration_AuthenticateDevice |
结束用户设备身份验证。 |
令牌生成前 | TokenGeneration_RefreshTokens |
用户尝试刷新身份和访问令牌时调用。 |
触发器 | triggerSource 值 | 事件 |
---|---|---|
用户迁移 | UserMigration_Authentication |
用户登录时进行迁移。 |
用户迁移 | UserMigration_ForgotPassword |
忘记密码流程中的用户迁移。 |
触发器 | triggerSource 值 | 事件 |
---|---|---|
自定义消息 | CustomMessage_SignUp |
用户在您的用户池中注册时的自定义消息。 |
自定义消息 | CustomMessage_AdminCreateUser |
当您创建用户作为管理员并且 Amazon Cognito 向他们发送临时密码时的自定义消息。 |
自定义消息 | CustomMessage_ResendCode |
现有用户请求新的确认代码时的自定义消息。 |
自定义消息 | CustomMessage_ForgotPassword |
用户请求重置密码时的自定义消息。 |
自定义消息 | CustomMessage_UpdateUserAttribute |
用户更改其电子邮件地址或电话号码并且 Amazon Cognito 发送验证代码时的自定义消息。 |
自定义消息 | CustomMessage_VerifyUserAttribute |
用户添加电子邮件地址或电话号码并且 Amazon Cognito 发送验证代码时的自定义消息。 |
自定义消息 | CustomMessage_Authentication |
配置了 SMS MFA 的用户登录时的自定义消息。 |