Промежуточное программное обеспечение распознавателя GraphQL для проверки подлинности

У меня есть API-интерфейс GraphQL со смешанными публичными и частными запросами и мутациями. Я ищу способ проверить, требует ли операция аутентификации пользователя, а также проверки прав доступа, чтобы пользователь мог изменять только свои собственные данные.

Я заметил, что функция распознавателя имеет четвертый аргумент, info это включает path.key который возвращает имя операции (задокументировано здесь).

Мое решение состояло в том, чтобы добавить функцию проверки внутри каждого распознавателя, вот так:

// modify user details
resolve: async (parent, args, { mongo: { User }, loggedUser }, info) => {
    // auth check
    authChecker(info.path.key, loggedUser, args.id);

  // continue resolving
},

И в другом файле:

function authChecker(operationName, loggedUser, userId) {
  if (PUBLIC_OPERATIONS.includes(operationName) {
    // public operation
    return true;
  } else {
    // private operation
    if (args.id) {
      // private operation that requires a permission check
      ...
    } else {
      // private operation that only requires user to be logged in
      ...
    }
  }
}

Функция либо возвращает true, либо выдает ошибку, если условия не выполняются.

Мне было интересно, было ли это хорошим решением или был ли способ сделать это с помощью промежуточного программного обеспечения, чтобы мне не пришлось повторять код в каждом распознавателе. Проблема в том, что у меня не было бы доступа к имени операции, если бы я использовал промежуточное программное обеспечение. Какие-либо предложения?

1 ответ

Решение

Использование промежуточного программного обеспечения должно быть возможным, но это будет болезненно, потому что вам придется анализировать запрос самостоятельно. Я думаю, что самый простой способ - это использовать преобразователь уровня схемы, который доступен с GraphQl-Tools.

const {makeExecutableSchema, addSchemaLevelResolveFunction} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs, resolvers})
addSchemaLevelResolveFunction(schema, (root, args, context, info) => {
  // check info to see if query is private and throw if user isn't authenticated
})
// use the schema like normal
app.use('/graphql', graphqlHTTP({schema}))

Решатель не должен ничего возвращать; он просто должен выбросить или вернуть отклоненное обещание, когда аутентификация не удалась. Для получения дополнительной информации о создании схемы с помощью GraphQl-инструментов, проверьте документы здесь.

Другие вопросы по тегам