Я пытаюсь аутентифицировать пользователя, прежде чем разрешить доступ к моей конечной точке / graphql.
Согласно документации Apollo-сервер относительно установки контекста, я могу сделать что-то вроде этого.
app.use(
'/graphql',
bodyParser.json(),
graphqlExpress(req => {
// Some sort of auth function
const userForThisRequest = getUserFromRequest(req);
return {
schema: myGraphQLSchema,
context: {
user: userForThisRequest,
},
// other options here
};
}),
);
Я пытаюсь использовать функцию authentication () паспортного JS в качестве заполнителя для «Какая-то функция аутентификации», но я не могу понять, как использовать параметр req, к которому у меня есть доступ. Должен ли я вызывать Passport.authenticate () после промежуточного программного обеспечения bodyParser или внутри метода graphqlExpress?
Итак, мой вопрос: как я могу использовать механизм аутентификации паспортного JS в этом контексте? Кроме того, это лучший способ реализовать аутентификацию на Apollo-сервере?





Есть несколько разных способов сделать это - в зависимости от типа ответа, который вы хотите отправить обратно своему клиенту при сбое аутентификации, и от того, сколько вам нужно для точной настройки процесса аутентификации.
Функция authenticate в Passport по сути является просто промежуточным программным обеспечением, поэтому вы можете делать что-то вроде:
app.use(
'/graphql',
bodyParser.json(),
authenticate(),
graphqlExpress(req => ({
schema: myGraphQLSchema,
context: {
user: getUserFromRequest(req),
},
}));
);
authenticate отправит ответ со статусом 401, если аутентификация не удалась (сам ответ зависит от того, как вы настроили обратный вызов проверки в своей стратегии паспорта). Это означает, что в случае сбоя аутентификации промежуточное ПО сервера Apollo никогда не будет вызвано.
В качестве альтернативы вы можете избежать использования authenticate и самостоятельно выполнить проверку аутентификации. Это можно сделать на уровне резолвера или для всех резолверов, используя инструмент graphql-tool addSchemaLevelResolveFunction.
импортировать {addSchemaLevelResolveFunction} из 'graphql-tools'
addSchemaLevelResolveFunction(executableSchema, (root, args, ctx, info) => {
if (!ctx.user) throw new CustomAuthenticationError()
})
Самая большая разница заключается в том, что ваш ответ теперь будет возвращать статус 200 и будет включать свойство нулевых данных и массив ошибок, который включает ошибку аутентификации.
Конечно, второй подход также позволяет точно настроить логику аутентификации - например, если вы хотите ограничить доступ только к подмножеству запросов или мутаций только для аутентифицированных пользователей. Если исключить это, я не знаю, лучше ли любой из этих подходов.