Я пытаюсь написать некоторую логику аутентификации на основе документации сервера Apollo, но, похоже, она не срабатывает. Вот мой код:
// schemas/auth-schema.js
import gql from 'graphql-tag';
export const typeDefs = gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
`;
// directives/auth-directive.js
import { SchemaDirectiveVisitor } from 'apollo-server';
export default class AuthDirective extends SchemaDirectiveVisitor {
visitObject(type) {
console.info('HERE');
}
visitSchema() {
console.info('HERE');
}
visitFieldDefinition() {
console.info('HERE');
}
}
// schemas/post-schema.js
import gql from 'graphql-tag';
import { Post } from '../models';
export const typeDefs = gql`
type Post @auth(requires: ADMIN) {
body: String!
description: String!
id: ID!
image: String!
publishedAt: DateTime
readingTime: Int!
slug: String!
title: String!
}
input PostInput {
body: String!
description: String!
image: String!
publishedAt: DateTime
title: String!
}
extend type Query {
posts: [Post!]! @auth(requires: ADMIN)
}
extend type Mutation {
addPost(input: PostInput!): Post! @auth(requires: ADMIN)
}
`;
export const resolvers = {
Query: {
posts: () => Post.find({}),
},
Mutation: {
addPost: (_, { input }) => Post.create(input),
},
};
// index.js
import { ApolloServer } from 'apollo-server';
import mongoose from 'mongoose';
import AuthDirective from './directives/auth-directive';
import * as config from './config';
mongoose.set('useNewUrlParser', true);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', config.env !== 'production');
const server = new ApolloServer({
modules: [
require('./schema/auth-schema'),
require('./schema/date-schema'),
require('./schema/post-schema'),
require('./schema/role-schema'),
require('./schema/user-schema'),
],
schemaDirectives: {
auth: AuthDirective,
},
});
async function boot() {
await mongoose.connect(config.mongo.url);
await server.listen(config.http.port);
console.info(`server listening on port ${config.http.port}`);
}
async function shutdown() {
await server.stop();
await mongoose.disconnect();
console.info(`server shutted down`);
process.exit(0);
}
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
boot();
Итак, я пробовал использовать директиву @auth во всех возможных случаях, и ничего не срабатывает.
type Post @auth(requires: ADMIN) { ... } // not firing
type Query {
posts: [Post!]! @auth(requires: ADMIN) // not firing
}
Вот что AdminDirective оценивает из консоли:

Что я делаю неправильно?
@DanielRearden Я использую сервер apollo версии 2.4.0.
Хм, я только что проверил этот код локально, и он отлично работает для меня.
Можете ли вы обновить свой вопрос, чтобы показать полный auth-schema.js?
Кроме того, если вы запишете значение для AuthDirective внутри index.js, будет ли оно отображаться как определено?
@DanielRearden отредактировано
Можете ли вы попробовать использовать makeExecutableSchema({ typeDefs, resolvers, schemaDirectives }); вместо модулей схемы. У меня также были проблемы с использованием свойства schemaDirectives в объекте конфигурации ApolloServer. Может быть проблема с ApolloServer


Итак, глядя на код для apollo-server, когда вы используете опцию modules, внутри ваша схема строится с использованием buildServiceDefinition. Хотя эта функция объединяет директивы всех модулей, она не передает ваш объект schemaDirectives и не применяет его.
Другими словами, это похоже на ошибку самого apollo-server. Вы можете подать заявку, а пока просто воспользоваться опциями typeDefs и resolvers, объединив нужные файлы самостоятельно.
Хорошо, похоже, если вы поменяете модули со схемой и используете makeExecutableSchema, все будет работать нормально. Жаль, с другой стороны все выглядело намного чище :'( Спасибо за вашу помощь и время!
Похоже, проблема уже была открыта, но на нее не обращали особого внимания: github.com/apollographql/аполло-сервер/issues/2046
@brielov Вы могли бы взглянуть на использование слияние-graphql-схемы в дополнение к makeExecutableSchema. Это то, что я на самом деле использую в одном проекте.
Я обязательно посмотрю на это. Спасибо!
На первый взгляд, эта установка выглядит правильной. Какую версию аполло-сервера вы используете?