5

我最近开始尝试使用 AWS AppSync,但我对 AWS Cognito 有一些疑问。

我希望用户能够通过 Facebook 进行身份验证,但我需要他们的个人资料图片、姓名和电子邮件作为我的应用程序中我的公共用户个人资料的数据。到目前为止,我注意到 Cognito 与 Facebook Auth 集成,但它不允许访问用户信息,并且此信息不会保存在 DynamoDB 表中。

我的问题是,当 Cognito 收到新登录时,如何在 DynamoDB 中创建新用户,或者当用户已经存在于数据库中时返回现有用户/ID。

4

3 回答 3

4

几周前我试图实现同样的目标。

在阅读了几个小时的文档后,我意识到 Cognito 可能无法帮助我们处理从 FB 返回的数据或如何保存它。

我最终做了以下事情:

(1) 使用FB-SDK,拉入用户数据。

(2) 调用 Lambda 函数,将这些数据(如 FB_id 等)保存到 DynamoDB。

(3) 如果用户再次登录,他们的 FB_id(或电子邮件)用于检查 DynamoDB 条目以检索他们的数据。

如果 Cognito 能够帮助我们并且我以某种方式错过了它,我很想知道。

快乐编码!

于 2017-12-18T13:48:06.417 回答
3

您可以在用户池中使用来自 Facebook的自定义属性和联合用户来实现此目的。以下是执行此操作的高级步骤。

  • 您首先必须为要保存在每个用户配置文件中的配置文件信息定义自定义属性。
  • 定义属性映射以将自定义属性链接到您要保存的 Facebook 属性。
  • 使用Cognito 托管页面和联合构建您的应用程序,以允许您的用户使用 Facebook 登录。

此后,在您的应用程序中的每个新用户登录时,都会在您的用户池中创建一个新用户,其中包含在属性映射中定义的所有属性以及 Cognito 在 Facebook 令牌中获取的值。您的应用将在身份验证后颁发的 IDToken 中获取这些属性值,您的应用可以使用这些属性值。

此外,如果您想将这些属性值存储在 Cognito 用户池配置文件之外,例如您自己的 DynamoDB 表,您可以在池中配置一个PreSignUp 触发器,该触发器将在所有新用户创建时调用。您可以将此触发器中的用户属性导出到您选择的任何数据库。

希望这可以帮助。

于 2017-12-20T22:52:49.043 回答
1

AWS AppSync 允许您访问 GraphQL 解析器中的信息,您可以选择将这些信息存储在 DynamoDB 表中。对于来自 Facebook 个人资料的数据,您可以将其作为参数传递给 GraphQL 突变或在 AppSync 的标头中传递,然后您可以通过$ctx.request.headers.NAME其中 NAME 是您的标头名称在解析器中访问。然后,您可以简单地选择要为该用户写入 DynamoDB 的哪些属性作为突变的一部分。更多信息在此处的参考指南中:https ://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html

由于您还要求先检查用户是否已经在 DDB 中,因此您可以先进行存在检查:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "userId": $util.dynamodb.toDynamoDBJson($ctx.identity.username),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(userId)"
  },
}

这会根据 Cognito 用户池中的用户名进行检查。如果您使用的是 Cognito Federated Identities 功能,它将是ctx.identity.cognitoIdentityId. 如果记录已经存在,则返回的响应将告诉您这意味着用户已经存在。您还可以通过查看$ctx.result条件语句并从头开始构建 JSON 响应或使用$util.error()上述指南中的方法之一来转换响应映射模板中返回的消息。

最后,正如您提到的,您将拥有公开的个人资料数据,您可能希望在某些记录上对此进行标记以进行控制。在 AWS AppSync 中,您可以过滤有关授权元数据的 GraphQL 响应,例如。您只需在 DynamoDB 记录上拥有一个标记为“公共”或“私有”的属性(即列)。然后您的响应模板将如下所示:

#if($context.result.public == 'yes')
    $utils.toJson($context.result)
#else
    $utils.unauthorized()
#end

您可以在此处查看更多示例:https ://docs.aws.amazon.com/appsync/latest/devguide/security-authorization-use-cases.html#public-and-private-records

于 2018-02-15T05:59:33.247 回答