Промежуточное программное обеспечение распознавателя 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-инструментов, проверьте документы здесь.