Как реализовать директиву auth для мутаций с Apollo? - PullRequest
0 голосов
/ 02 января 2019

Я пытаюсь настроить бэкэнд Apollo для проекта, над которым я работаю, где я пытаюсь реализовать директивы схемы.Однако я не могу добавить свою директиву схемы к мутациям.Итак, на мой главный вопрос: как мне реализовать директиву auth для мутаций?

Я добавил @auth(requires: ADMIN) в конец моего запроса пользователей, который работает нормально.Затем Apollo потребует токен на предъявителя с правами администратора для выполнения запроса пользователей.

extend type Query {
    user(id: ID!): User
    users: [User!]! @auth(requires: ADMIN)
}

Когда я попытался сделать то же самое для мутации editMyUser, директива auth, похоже, применяется для всехмутации, а не только ту, которую я хотел.Даже мутация signUp выдаст ошибку «not authorised», когда я добавлю часть @auth к мутации editMyUser.Даже при том, что между ними нет никакой связи.

Поле роли, которое должно быть передано директиве auth при вызове, выходит из системы пустым.

extend type Mutation {
    signUp(
        username: String!
        firstName: String
        lastName: String
        password: String!
        isAdmin: Boolean
        isActive: Boolean): User!
    login(
        username: String!
        password: String!): User!
    editMyUser(
        id: ID!
        firstName: String
        lastName: String
        password: String): User! @auth(requires: USER)
    adminEditUser(
        id: ID!
        firstName: String
        lastName: String
        password: String
        isActive: Boolean
        isAdmin: Boolean
        isBanned: Boolean): User!
}

Вот как я реализовалдиректива схемы

export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION

enum Role {
    ADMIN
    USER
}

https://github.com/jwhenshaw/graphql-directives-auth Это директива Auth, которую я реализовал в своем коде для справки.

Итак, подведем итог: когда я реализую директивы auth для мутаций, они реализуются для всех мутаций, а не только для одной, и она даже не работает правильно, поскольку роли не передаются в директиву.

Я бы хотел помочь с этим.Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 января 2019

В этом репозитории класс AuthDirective передает objectType поля, включаемого в метод ensureFieldWrapped. Это означает, что для вашего примера, когда вы назначаете директиву непосредственно в поле editMyUser объекта Mutation, метод оборачивает все дочерние элементы Mutation (я считаю, что то же самое должно быть верно для ваши запросы, а на самом деле).

Итак, в примере репозитория это нормально, так как у нас есть тип объекта User, и мы обертываем его и его поля. Однако, если вы не хотите делать это, мы можем изменить класс AuthDirective, чтобы обернуть только поле, в котором он находится.

Я сделал это и подтолкнул к репо, https://github.com/jwhenshaw/graphql-directives-auth,, где вы можете видеть, что теперь есть FieldAuthDirective и ObjectAuthDirective. Мне все еще нужно немного почистить код, но я привел рабочий пример и оставил несколько журналов, чтобы подчеркнуть различия. Вы можете просмотреть его здесь https://qzj70qn2mj.sse.codesandbox.io/, если не хотите запускать его локально.

Надеюсь, это поможет, дайте мне знать, если мне нужно уточнить еще.

0 голосов
/ 02 января 2019

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

Логика заключается в том, что, поскольку вы используете директиву для некоторого поля типа объекта, вам также необходимо предоставить требование для самого типа.По моему мнению, эта логика не так уж и плоха, и, как следует из комментария к коду, она находится на безопасной стороне.Автор этой реализации, вероятно, сосредоточился на использовании директивы для реальных типов данных, а не для запросов или мутаций.

Позвольте мне быть даже более конкретным: что мы с вами делаем (как я пытаюсь выполнитьто же самое, что и вы сегодня), при использовании директивы для одного или нескольких запросов / мутаций фактически применяется директива к полям типов схем Query и Mutation.Поэтому, если мы не хотим минимального требования для всех запросов и / или мутаций нашей схемы, код не должен выдавать ошибку в том условии, которое я связал выше, но он должен вызывать упакованный преобразователь, как если бы требования были выполнены (потому что их нет).

Пример:

if (!requiredRole) {
  // No auth required, just call the resolver
  return resolve.apply(this, args);
}

Надеюсь, это поможет!?

...