在 AWS 文档或 Github 中确实没有足够的文档,所以希望这里有人解决了类似的问题。
我有一个使用 appsync、dynamoDB 和 cognito-user-pools 托管在 AWS 上的后端 api 的反应应用程序。我的 IAM 策略设置为允许未经身份验证的用户对某些公共表具有只读权限。我尝试了公共 api 密钥,但没有做任何事情。我正在尝试设置 IAM unauth 角色权限,但即使我实验性地将每个服务和每个操作添加到 unauth 角色,在尝试在不登录的情况下进行 API 调用时,我仍然会得到“没有当前用户”。
用例用于公共作者页面,其中列出了有关作者的信息及其当前可用的书籍。用户无需登录即可查看此页面,作者应该能够将指向该页面的链接拖放给任何人,无论他们是否拥有该应用程序的登录名。
这是我的相关类型的 graphql 模式,它没有错误:
type PublicBook @model @auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
@key(name:"byPublicWorld", fields: ["publicWorldId", "indexOrder"])
@key(name:"byPublicSeries", fields: ["publicSeriesId", "indexOrder"]){
id: ID!
publicWorldId: ID
publicSeriesId: ID
indexOrder: Int!
cover: FileObject @connection
description: String
amazon: String
ibooks: String
smashwords: String
kobo: String
goodreads: String
audible: String
barnesnoble: String
sample: String
}
type PublicSeries @model @auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
@key(name:"byPublicWorld", fields: ["publicWorldId", "indexOrder"]){
id: ID!
publicWorldId: ID!
indexOrder: Int!
logo: FileObject @connection
description: String
genre: String
books: [PublicBook]@connection(keyName:"byPublicSeries", fields: ["id"])
}
type PublicWorld @model @auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
@key(name:"byAuthorPage", fields: ["authorPageId", "indexOrder"]){
id: ID!
authorPageId: ID!
logo: FileObject @connection
description: String
genre: String
indexOrder: Int!
series: [PublicSeries]@connection(keyName:"byPublicWorld", fields: ["id"])
books: [PublicBook]@connection(keyName:"byPublicWorld", fields: ["id"])
}
type AuthorPage @model @auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
@key(name:"byPenName", fields: ["penId"])
@key(name:"byPenDisplayName", fields: ["penDisplayName"], queryField: "authorPageByPen"){
id: ID!
authorName: String
penDisplayName: String
penId: ID!
bio: String
photo: FileObject @connection
logo: FileObject @connection
penFBProfile: String
penFBGroup: String
penFBPage: String
penTwitter: String
penInstagram: String
penAmazon: String
penWebsite: String
penNewsletter: String
penGoodreads: String
penPatreon: String
posts: [AuthorPost]@connection(keyName:"byAuthorPage", fields: ["id"])
worlds: [PublicWorld]@connection(keyName:"byAuthorPage", fields: ["id"])
}
type AuthorPost @model @auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
@key(name:"byAuthorPage", fields: ["authorPageId", "timeCreated"]){
id: ID!
authorPageId: ID!
timeCreated: AWSTimestamp!
content: String!
title: String!
subtitle: String
type: PostType!
}
这些类型中的每一种都设置为所有者/认知权限,用于创建、更新和删除,然后有一个使用 iam 读取的公共 auth。似乎很直截了当。
这里的主要类型是作者页面,我设置了查询以提取所有连接的相关级联信息。登录后,这可以正常工作并显示一个包含所有内容的作者页面:
export const authorPageByPen = /* GraphQL */ `
query AuthorPageByPen(
$penDisplayName: String
$sortDirection: ModelSortDirection
$filter: ModelAuthorPageFilterInput
$limit: Int
$nextToken: String
) {
authorPageByPen(
penDisplayName: $penDisplayName
sortDirection: $sortDirection
filter: $filter
limit: $limit
nextToken: $nextToken
) {
items {
id
authorName
penDisplayName
penId
bio
photo {
location
}
logo {
location
}
penFBProfile
penFBGroup
penFBPage
penTwitter
penInstagram
penAmazon
penWebsite
penNewsletter
penGoodreads
penPatreon
posts {
nextToken
startedAt
}
worlds {
nextToken
startedAt
}
_version
_deleted
_lastChangedAt
createdAt
updatedAt
owner
}
nextToken
startedAt
}
}
`;
在页面本身上(尽管在生产中这只是发生在 app.js 并在整个应用程序中持续存在),我正在提取当前凭证并记录它们以确保正在创建某种 IAM 身份,它似乎是:
accessKeyId: "BUNCHANUMBERSKEY"
authenticated: false
expiration: Thu Mar 04 2021 13:18:04 GMT-0700 (Mountain Standard Time) {}
identityId: "us-west-2:48cd766c-4854-4cc6-811a-f82127670041"
secretAccessKey: "SecretKeyBunchanumbers"
sessionToken:"xxxxxbunchanumbers"
第identityId
4 行的内容作为未经身份验证的身份存在于我的身份池中,因此它正在返回池中,这似乎是应该发生的事情。
所以,这个身份池有两个与之关联的角色,这是标准的:auth 和 unauth,我的未验证身份设置有选中的框Enable Access to Unauthenticated Identities
。
在我的 unauth 角色中,我将以下内容作为内联策略 json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppsyncApiId/types/Mutation/fields/authorPageByPen"
]
}
]
}
我不确定这是否需要突变、查询或什么,所以我都试过了。我尝试将它们与“字段”和“索引”结合使用,我尝试编写 JSON,并从内联编辑器添加策略,这给了我以下内容也不起作用:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "appsync:GraphQL",
"Resource": [
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppSyncAPIId/types/AuthorPage/fields/authorPageByPen",
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppSyncAPIID"
]
}
]
}
我在这里缺少什么?我可以理解有关不允许访问资源的一些错误,但记录的唯一错误是,并且在显示用户No Current User
的日志之后立即发生。
更新:从 Appsync 控制台运行查询适用于 IAM 并且没有登录用户。在页面本身中,我使用以下函数来调用作者页面(我正在使用路由):
const pullAuthorPage = async () => {
try{
const authorPageData = await API.graphql(graphqlOperation(authorPageByPen, { penDisplayName: props.match.params.id.toLowerCase() }))
console.log(JSON.stringify(authorPageData, null, 2));
setState({...authorPageData.data.authorPageByPen.items[0]})
} catch (error) {
console.log(error);
}
}
我认为会发生这种情况的是,如果没有经过身份验证的用户登录,这将使用 unauth 用户凭据运行。不是这样吗?如果是这样,我应该如何改变它?