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

vah*_*det 11 authentication amazon-web-services amazon-cognito aws-appsync aws-amplify

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

aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS'
Run Code Online (Sandbox Code Playgroud)

当用户通过身份验证时,它会按预期工作;然而(尽管涉及的 Cognito 身份池已经设置了适当的 Auth 和 Unath 角色),当网站运行一些 Amplify fetch 命令时,例如针对未经身份验证的(来宾)用户:

aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS'
Run Code Online (Sandbox Code Playgroud)

以抛出错误结束:

"No current user"
Run Code Online (Sandbox Code Playgroud)

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

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

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

有可能吗?


1我有更精细的控制,具体取决于用户组(管理员、普通等)以及@aws_auth(cognito_groups: ["default-user-group"])AppSync 架构等装饰器。因此,我需要 Cognito 用户池来实现该用途。

Raf*_*ael 6

所以,我刚刚经历了类似的问题并设法解决了它。我希望这可以帮助你解决这个问题。您在问题中提到的SO问题几乎是正确的方法。然而,有一个“小”的细节没有记录下来,我花了一段时间才找到。

除了必须通过运行启用经过身份验证和未经身份验证的访问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 }
    ]
  )
Run Code Online (Sandbox Code Playgroud)

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

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

代替

const item = await API.graphql(graphqlOperation(getItem, { id: 'my-id' }))
Run Code Online (Sandbox Code Playgroud)

尝试类似的东西

// 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,
  }));

Run Code Online (Sandbox Code Playgroud)

顺便说一句,“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;
  }
}
Run Code Online (Sandbox Code Playgroud)

所以...这行就是它的作用,这并没有得到很好的记录。

authMode: isLoggedIn ? GRAPHQL_AUTH_MODE.AMAZON_COGNITO_USER_POOLS : GRAPHQL_AUTH_MODE.AWS_IAM

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

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