Я пытаюсь выяснить, как вы можете защитить на уровне поля один-ко-многим @connection с @auth от мутаций, которые не должны быть разрешены. (то есть: запретить конкретному пользователю запускать мутацию, которая в конечном итоге приведет к вставке сообщений от имени другого пользователя.)
Начиная с примера защиты мутации на уровне поля: https://aws-amplify.github.io/docs/cli/graphql#авторизация на уровне поля
Я попытался сделать что-то вроде этого:
type User @model @auth(rules: [{ allow: owner, ownerField: "id" }]) {
id: ID!
posts: [Post]
@connection(name: "UserPosts")
@auth(rules: [{ allow: owner, ownerField: "id" }])
}
type Post @model {
title: String!
user: User!
@connection(name: "UserPosts")
@auth(rules: [{ allow: owner, ownerField: "userPostId" }])
}
Затем скажите, что уже есть пользователь с идентификатором regular-user-id
По-видимому, мои правила авторизации не мешают другому пользователю, скажем, с идентификатором: malicious-user-id запустить эту мутацию:
mutation {
createPost(input:{
title:"Oh this is BAD!"
postUserId: "regular-user-id"
}) {
title
}
}
Выполнение простого запроса, чтобы убедиться, что это действительно произошло:
query {
getUser(id:"regular-user-id"){
posts{
items
{
title
}
}
}
}
=>
{
"data": {
"getUser": {
"posts": {
"items": [
{
"title": "Regular User title"
},
{
"title": "Oh this is BAD!"
},
]
}
}
}
}
Я пробовал разные способы выяснить это и не смог найти никакой документации о двунаправленной аутентификации на уровне полей. Я довольно новичок в AppSync, поэтому я думаю, что, должно быть, что-то не понимаю, но это настолько распространенный сценарий использования, что я действительно удивлен, что нет больше документации об этом.
Некоторая помощь была бы очень признательна.


Должен ли злоумышленник иметь возможность обновить заголовок Post? Я знаю, что это не точный ответ на ваш вопрос, поскольку вы сосредоточены на поле отношений, но, пытаясь понять, как делать такие вещи самостоятельно, я прочитал несколько вещей о введении некоторой формы группы «все». так что вы можете определить авторизацию для пользователей, которые не являются владельцами. Затем вы можете поставить авторизацию на всю модель Post, чтобы только владельцы могли обновлять любое поле;
type Post
@model
@auth(rules: [
{ allow: owner, ownerField: "userPostId" },
{ allow: groups, groups: ["everyone"], operations: [read] }
]) {
title: String!
user: User!
@connection(name: "UserPosts")
}
Я новичок в усилении (в настоящее время я оцениваю, использовать ли его для проекта, который я начинаю), поэтому я могу ошибаться здесь. Если вам действительно нужна полуоткрытая модель, в которой только поле ссылки имеет аутентификацию, я не знаю, как это сделать :(
Поле владельца будет «postUserId», а не «userPostId», что может вызвать путаницу. Вы также можете явно установить ключевые поля, используя аргументы «keyField» и «sortField» в @connection.
Чтобы защитить мутацию Mutation.createPost, чтобы только владелец сообщения, указанный с помощью postUserId, мог получить к нему доступ, вы добавляете директиву @auth в определение объекта Post:
type Post @model @auth(rules: [{ allow: owner, ownerField: "postUserId" }]) {
title: String!
# This will use a field 'postUserId' by default.
user: User!
@connection(name: "UserPosts")
}
С этой установкой мутация:
mutation {
createPost(input:{
title:"Oh this is BAD!"
postUserId: "regular-user-id"
}) {
title
}
}
произойдет сбой, если вошедший в систему пользователь не является «обычным идентификатором пользователя».
Этот ответ также может помочь заполнить информацию https://github.com/aws-amplify/amplify-cli/issues/1507#issuecomment-513042021.
Речь не идет об обновлении после того, как сообщение было создано. Это прекрасно работает. Проблема в создании поста. Я не мог найти способ предотвратить, скажем, UserB запуск мутации, когда он указывает, что сообщение принадлежит другому пользователю, скажем, UserA.