“没有当前用户”:是不是甚至可以通过 Amplify 使用身份验证类型 AMAZON_COGNITO_USER_POOLS 对 AWS AppSync 进行未经身份验证的调用?

Posted

技术标签:

【中文标题】“没有当前用户”:是不是甚至可以通过 Amplify 使用身份验证类型 AMAZON_COGNITO_USER_POOLS 对 AWS AppSync 进行未经身份验证的调用?【英文标题】:"No current user": Isn't it even possible to make unauth calls to AWS AppSync through Amplify with authentication type AMAZON_COGNITO_USER_POOLS?“没有当前用户”:是否甚至可以通过 Amplify 使用身份验证类型 AMAZON_COGNITO_USER_POOLS 对 AWS AppSync 进行未经身份验证的调用? 【发布时间】:2020-11-24 14:53:51 【问题描述】:

我有一个默认授权模式设置为 Amazon Cognito 用户池 的 AWS AppSync 架构。我使用 AWS Amplify GraphQL Client 从 Web 应用程序调用此 AppSync 端点,并且连贯地,它的配置也将 Cognito 用户池作为身份验证类型:

aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS'

当用户被认证时,它会按预期工作;但是(尽管涉及的 Cognito 身份池已经设置了适当的 Auth 和 Unath 角色),当网站运行一些 Amplify fetch 命令时,例如 unauthenticated(guest) 用户:

const item = await API.graphql(graphqlOperation(getItem,  id: 'my-id' ))

最终抛出错误:

"No current user"

好吧,如果我允许未经身份验证的用户,我希望它能够执行,但它只是失败了。寻找出路,我发现了一些讨论,例如:

GitHub 问题评论here, 另一个Github issue, 或一个 SO 问题 here。

而且,以上所有建议都建议重新访问 Amplify 配置,以便将 AppSync 身份验证类型从 AMAZON_COGNITO_USER_POOLS 转换为 AWS_IAMAPI_KEY。但是,由于某些详细原因1

我想坚持AMAZON_COGNITO_USER_POOLS身份验证类型, 并且仍然能够以访客用户的身份获取一些 AppSync 资源,除非它们受到限制 @aws_auth 装饰师之类的。

有没有可能?


1 我有更精细的控件,具体取决于用户组(管理员、普通等),在 AppSync 架构上使用 @aws_auth(cognito_groups: ["default-user-group"]) 等装饰器。所以,我需要 Cognito 用户池来使用。

【问题讨论】:

嘿,你有什么解决办法吗?? 同样的问题。我的 api 要求我有 cognito pools 方法,但是在未经身份验证的情况下我将无法查询。 【参考方案1】:

所以,我刚刚经历了一个类似的问题并设法对其进行了排序。我希望这可以帮助你解决这个问题。您在问题中提到的SO question 几乎是正确的方法。但是,有一个“小”小细节没有记录在案,我花了一段时间才找到。

除了必须通过运行 amplify update auth 启用经过身份验证和未经身份验证的访问(您可以在上面链接的 SO 中看到如何)之外,您还需要进行其他调整。

首先,在您的模型中,您需要将规则调整为:

  @auth(
    rules: [
      # allow owners ability to update and delete their these messages (user pools)
       allow: owner ,
      # allow all authenticated users to access this data
       allow: private, provider: userPools ,
      # allow all guest users (not authenticated) to access this data
       allow: public, provider: iam 
    ]
  )

一旦您设置此模型以允许用户池访问他们“拥有”的所有数据,您也可以让任何“访客”用户也访问数据。

在前端,让我们以您的代码为例,您需要使用一些不同的方法:

代替

const item = await API.graphql(graphqlOperation(getItem,  id: 'my-id' ))

试试类似的东西

// Check if the user is logged in or not
let isLoggedIn = await isLoggedIn();

const item = (await API.graphql(
      query: getItem,
      variables:  id: 'my-id' ,
      authMode: isLoggedIn ? GRAPHQL_AUTH_MODE.AMAZON_COGNITO_USER_POOLS : GRAPHQL_AUTH_MODE.AWS_IAM,
  ));

顺便说一下,“isLoggedIn”函数看起来像这样

async function isLoggedIn() 
  // Another way to get if its a guest or not
  //return await Auth.Credentials.getCredSource() === "guest"
  try 
      await Auth.currentAuthenticatedUser();
      return true;
   catch 
      return false;
  

所以...这一行就是它的诀窍,但并没有很好的记录。

authMode: isLoggedIn ? GRAPHQL_AUTH_MODE.AMAZON_COGNITO_USER_POOLS : GRAPHQL_AUTH_MODE.AWS_IAM

您需要根据用户的状态(登录或访客)来路径不同的方法,而不仅仅是 AWS_IAM 一个。

这只会让您阅读数据,以确保客人可以创建/更新/删除,并将数据所有权与彼此和登录用户分开,这是您需要的完全不同的故事开始挖掘解析器以对其进行排序。但好消息是,有办法:)

【讨论】:

以上是关于“没有当前用户”:是不是甚至可以通过 Amplify 使用身份验证类型 AMAZON_COGNITO_USER_POOLS 对 AWS AppSync 进行未经身份验证的调用?的主要内容,如果未能解决你的问题,请参考以下文章

Cognito Auth.sendCustomChallengeAnswer 给出“AuthClass - 无法获取登录用户没有当前用户”

将手动创建的 Cognito 用户池与放大项目一起使用

没有当前用户 - getServerSideProps Next JS 和 AWS Amplify

没有当前用户 AWS Amplify 身份验证错误 - 无需登录即可访问

将用户添加至sudoers列表

Smack:是不是有必要(甚至可能)明确关闭聊天?