Есть ли способ настроить авторизацию на уровне поля на FaunaDB + GraphQL?

У меня проблемы с поиском способа скрыть электронные письма пользователей от всех, кроме владельца (у пользователя есть доступ только к своей электронной почте). Есть ли способ скрыть определенное поле документа для определенных ролей?

Вот пример, который я обнаружил, который создает роль с динамическим доступом ко всей коллекции User:

CreateRole({
  name: "tier1_role",
  membership: {
    resource: Collection("User"),
    predicate: Query(
      Lambda("userRef",
        // User attribute based rule:
        // It grants access only if the User has TIER1 role.
        // If so, further rules specified in the privileges
        // section are applied next.
        Equals(Select(["data", "role"], Get(Var("userRef"))), "TIER1")
      )
    )
  },
  privileges: [
    {
      // Note: 'allUsers' Index is used to retrieve the
      // documents from the File collection. Therefore,
      // read access to the Index is required here as well.
      resource: Index("allUsers"),
      actions: { read: true }
    }
  ]
})

Я попытался немного изменить его, но мне не удалось настроить доступ на уровне поля.

Скажем, я бы установил FaunaDB со схемой GraphQL ниже.

enum UserRole {
  TIER1
}

type User {
  email: String! @unique
  username: String! @unique
  role: UserRole!
}

type Query {
  allUsers: [User!]
}

type Mutation {
  addUsers(new_users: [UserInput]): [User]
    @resolver(name: "add_users", paginated: false)
}

Как создать роль FaunaDB таким образом, чтобы у всех пользователей (кроме текущего) в результирующем массиве из запроса allUsers не было поля email?

Я мог бы разбить User коллекцию на две части: одна общедоступна, другая доступна владельцу документа, но это звучит неправильно.

Я новичок в концепции noSQL, так что, может быть, я смотрю на эту проблему с неправильной точки зрения?


person Mike M    schedule 24.02.2020    source источник


Ответы (1)


это запрос, который возникал несколько раз. Вы, вероятно, захотите сделать это прямо в ролевой системе ABAC FaunaDB, но, хотя она обеспечивает безопасность на уровне строк, скрытие определенного поля в настоящее время еще не предусмотрено. Отзыв уже записан, мы его рассмотрим.

Текущий способ сделать это - отделить пользователей от учетных записей и получить пользователей вместо учетных записей. Хотя в будущем было бы полезно иметь что-то вроде скрытых полей.

Если вы думаете об этом, в этом случае имеет смысл отделить информацию для аутентификации от информации о пользователе. Никогда не предвидится, что в будущем вы можете предложить другой способ аутентификации. Я до сих пор помню из книги Phoenix Framework, что они там сделали это хорошо и считали это хорошей практикой.

Вы также можете создать тонкую оболочку, используя Apollo в бессерверной функции, и отфильтровать эти поля при просмотре результатов. Существует руководство, объясняющее, как создать такое тонкое промежуточное ПО Apollo, которое просто делегирует FaunaDB https://www.gatlin.io/blog/post/social-login-with-faunadb-and-auth0

person Brecht De Rooms    schedule 22.04.2020
comment
Я действительно сделал, как сказано в вашем предложении, в качестве временного решения, пока не будет найден способ скрыть поля. Но он оказался достаточно хорошим, он выполняет свою работу, плюс ваш ответ убедил меня, что это один из правильных способов сделать это. Спасибо за ваш ответ! Я отвечу фрагментами кода позже. - person Mike M; 24.04.2020