为了保护GraphQL查询中的字段,可以使用Schema Directives来实现对字段的访问控制。下面是一个针对GraphQL的Schema Directives示例,用于保护字段不被查询:
import { SchemaDirectiveVisitor } from 'graphql-tools';
import { defaultFieldResolver } from 'graphql';
class ProtectFieldsDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
const [, , context] = args;
if (!context.user) { //此处可以加上自己的业务逻辑判断如某个用户是否有权限访问
throw new Error(`Unauthorized access to field ${field.name}`);
}
return resolve.apply(this, args);
};
}
}
然后在构建Schema时使用该Directive:
import { makeExecutableSchema } from 'graphql-tools';
const typeDefs = `
type User {
id: ID!
name: String
email: String @protectFields
}
type Query {
user(id: ID!): User
}
schema {
query: Query
}
`;
const resolvers = {
User: {
email(user, args, context) {
return user.email; //仅当context.user存在时才会返回query中的email字段
}
},
Query: {
user(_, { id }) {
return getUserById(id);
}
}
};
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
schemaDirectives: {
protectFields: ProtectFieldsDirective
}
});