在 AWS Lambda 中维护会话状态
Maintain session state in AWS Lambda
如何在 AWS Lambda 中维护会话状态?例如,如果我需要查询 DynamoDb 以获取登录用户的订阅信息,如果用户使用的是 [,我该如何从 Lambda 函数执行此操作? =39=] 网络应用程序?
我让用户使用 Auth0 和一个在 AWS 上验证用户的自定义授权方登录。但是后来我想使用登录用户的 CognitoID
来查询 DynamoDB。
根据 Lambda 的 AWS 文档 (node.js) (https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html),当通过 AWS Mobile SDK 调用时,您只有关于 Amazon Cognito 身份提供商的信息。
identity.cognitoIdentityId
identity.cognitoIdentityPoolId
但是,如果我使用使用 AngularJS 和 Auth0 的网络应用程序怎么办?
好的,也许在 DynamoDB 中存储用户信息的最简单的解决方案就是在客户端提取 JWT,在 AngularJS 中,然后发送提取的Auth0 user_id
— 例如 facebook|12345
— 在对 Lambda 的 API 请求中,它查询用户是否存在于 DynamoDB 中,如果不存在则创建新记录。
然后在每个必须查询用户信息的 API 请求中,我发送 user_id
并在 Lambda 中查询具有该 ID 的数据库。它应该是安全的,因为我在自定义授权器中验证用户令牌并在请求到达 Lambda 之前拒绝或允许该请求。
首先,Lambda 被用作无状态计算服务。因此,在 Lambda 中保持会话状态是不切实际的。
根据您的情况,您可以使用 jwt 令牌向 API 网关发送请求,您可以在其中插入一个特殊的 Lambda 函数调用 Custom Authorizer,您可以在其中验证令牌并提取用户id,然后转发到连接到 API 网关端点的业务逻辑 Lambda 函数。正如您在 Custom Authorizer 中提到的,您可以查询用户数据库和 return 业务逻辑 Lambda 的更多信息。
如果令牌无效或已过期,您可以 return 来自自定义授权方 Lambda 函数的错误,以便 API 网关发回错误响应而不会到达端点 Lambda。
此外,您还可以缓存 Custom Authorizer Lambda 的输出,以便为给定的 TTL 缓存它以提高性能并降低成本。
我已经这样做了,虽然我意识到可能有更好的解决方案:
为用户和会话维护 DynamoDB table。当用户使用 Cognito 登录时,使用 UUID、用户名和上次访问的时间戳在 Sessions table 中创建一个新项目。对于登录用户的所有后续调用,在 Session table 中查找用户名,并更新上次访问时间。然后,您可以将任何会话值存储在会话 table 中,或单独的 table 也具有会话 ID。
如果用户使用 Cognito 注销,则删除(或标记为已结束)会话项及其所有数据。如果您看到 lastAccessed 时间超过一个小时(或您想要的任何保持活动时间),则删除(或标记为已结束)该会话项及其所有数据。
如何在 AWS Lambda 中维护会话状态?例如,如果我需要查询 DynamoDb 以获取登录用户的订阅信息,如果用户使用的是 [,我该如何从 Lambda 函数执行此操作? =39=] 网络应用程序?
我让用户使用 Auth0 和一个在 AWS 上验证用户的自定义授权方登录。但是后来我想使用登录用户的 CognitoID
来查询 DynamoDB。
根据 Lambda 的 AWS 文档 (node.js) (https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html),当通过 AWS Mobile SDK 调用时,您只有关于 Amazon Cognito 身份提供商的信息。
identity.cognitoIdentityId
identity.cognitoIdentityPoolId
但是,如果我使用使用 AngularJS 和 Auth0 的网络应用程序怎么办?
好的,也许在 DynamoDB 中存储用户信息的最简单的解决方案就是在客户端提取 JWT,在 AngularJS 中,然后发送提取的Auth0 user_id
— 例如 facebook|12345
— 在对 Lambda 的 API 请求中,它查询用户是否存在于 DynamoDB 中,如果不存在则创建新记录。
然后在每个必须查询用户信息的 API 请求中,我发送 user_id
并在 Lambda 中查询具有该 ID 的数据库。它应该是安全的,因为我在自定义授权器中验证用户令牌并在请求到达 Lambda 之前拒绝或允许该请求。
首先,Lambda 被用作无状态计算服务。因此,在 Lambda 中保持会话状态是不切实际的。
根据您的情况,您可以使用 jwt 令牌向 API 网关发送请求,您可以在其中插入一个特殊的 Lambda 函数调用 Custom Authorizer,您可以在其中验证令牌并提取用户id,然后转发到连接到 API 网关端点的业务逻辑 Lambda 函数。正如您在 Custom Authorizer 中提到的,您可以查询用户数据库和 return 业务逻辑 Lambda 的更多信息。
如果令牌无效或已过期,您可以 return 来自自定义授权方 Lambda 函数的错误,以便 API 网关发回错误响应而不会到达端点 Lambda。
此外,您还可以缓存 Custom Authorizer Lambda 的输出,以便为给定的 TTL 缓存它以提高性能并降低成本。
我已经这样做了,虽然我意识到可能有更好的解决方案:
为用户和会话维护 DynamoDB table。当用户使用 Cognito 登录时,使用 UUID、用户名和上次访问的时间戳在 Sessions table 中创建一个新项目。对于登录用户的所有后续调用,在 Session table 中查找用户名,并更新上次访问时间。然后,您可以将任何会话值存储在会话 table 中,或单独的 table 也具有会话 ID。
如果用户使用 Cognito 注销,则删除(或标记为已结束)会话项及其所有数据。如果您看到 lastAccessed 时间超过一个小时(或您想要的任何保持活动时间),则删除(或标记为已结束)该会话项及其所有数据。