我有以下架构:
input CreateEventInput {
userID: String!
eventID: ID!
type: String!
data: String
dateTime: AWSDateTime!
}
type Mutation {
createEvent(input: CreateEventInput!): event
}
type Subscription {
onCreateEvent(): event
@aws_subscribe(mutations: ["createEvent"])
createEvent
解析器将userID
设置为:
"key" : {
"userID" : $util.dynamodb.toDynamoDBJson($context.identity.username),
"eventID" : $util.dynamodb.toDynamoDBJson($util.autoId())
}
我想限制订阅,以便仅记录userID = $context.identity.username
返回给用户的位置。
有人知道如何设置吗?我认为我需要在订阅上使用解析程序,但是在其中有主分区键(userID
)和主排序键(eventID
)的情况下,我找不到明确的示例。
我将非常感谢您的帮助或指导。我可以根据需要更改架构或数据库。
更新:
我相信我可以将“订阅响应映射模板”设置为:
#if(${context.identity.username} != ${context.arguments.userID})
$utils.unauthorized()
#else
##User is authorized, but we return null to continue
null
#end
但是,我不知要在请求映射模板中添加什么。
答案 0 :(得分:2)
我认为,通过将“输入”形状分解为突变的各个输入,对您的架构进行较小的更新最容易完成基于用户过滤订阅的第一步。具体来说:
type mutation {
createEvent(userID: String!, eventID: ID!, type: String!,
data: String, dateTime: AWSDateTime!): event
}
... other stuff...
type Subscription {
onCreateEvent(userId: String!): event
@aws_subscribe(mutations: ["createEvent"])
}
一些注意事项:
1)假设您希望这是订阅的要求。如果不是,如果希望它成为可选规则,请删除!。通过您的评论,我相信您会想要它。
2)订阅过滤器(这是订阅操作中的userId参数)要求过滤器位于对突变的响应中。因此,请确保在客户端上定义操作时,在响应中包括userId。
3)这是应用订阅过滤器所必需的。除非它是对突变的直接输入,否则该服务将不知道userId是什么,将其包含在内部并且输入形状将不起作用。
现在,要确定用户不能只订阅其他人的用户名。我相信您正在看this docs page。这将起作用,完全有效,并且可以通过类似于该文档页面中示例的内容来完成,但是它基于具有权限查找表和Dynamo解析器的基础。如果您没有一个,或者希望避免使用一个,则只需稍作调整就能使其与无/本地解析器一起使用。没有权限表或任何要检查的内容,我强烈建议您使用本地/无解析程序。
具体来说,我相信您可以将响应映射模板中的内容移到新的无/本地解析器的映射模板中。
#if(${context.identity.username} != ${context.arguments.userID})
$utils.unauthorized()
#else
##User is authorized, but we return null to continue
null
#end
...并且将响应映射模板作为默认响应,那么您将在权限表或无用代码中设置不必要的基础架构,以免发生无法进行的dynamo交互。取而代之的是,只需对照Cognito令牌中的用户名检查输入中的用户名即可。
答案 1 :(得分:0)
在Appsync进行改进之前,这里是我完成订阅的方式,该订阅仅允许用户使用我上面发布的架构来订阅与其自己的userID匹配的事件:
请求映射模板:
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"userID": $util.dynamodb.toDynamoDBJson($ctx.identity.username),
"eventID": { "S" : "0bfe0d7c-b469-441e-95f6-788fe300f76d" }
},
}
请求映射模板仅用于外观(Appsync Web控制台在您未填充有效内容的情况下将不允许您保存)每次有人提出订阅请求时,都会进行硬编码查找。这只会成功,只会丢弃数据。这就是订阅在Appsync中的工作方式。
订阅响应映射模板:
#if(${context.identity.username} != ${context.arguments.userID})
$utils.unauthorized()
#else
##User is authorized, but we return null to continue
null
#end
这就是魔术发生的地方。这基本上是说,如果用户没有请求订阅与他们自己的用户名相同的事件,则返回unauthorized
。如果用户已经请求订阅具有与登录帐户相同的用户ID的事件,则null
(null是响应映射模板成功继续(即不出错)的方式。< / p>
为彻底起见,这是客户要求的样子:
const eventSub = `subscription eventSub($userID: String!) {
onCreateEvent(userID: $userID) {
userID
email_hash
eventID
type
data
dateTime
}
}`;