我想使用自定义指令来保护我的GraphQL API。更具体地说,对于特定的GraphQL字段,我想检查当请求到达我的GraphQL服务器时用户是否有权查询这些字段。
以下链接是包含实现此目标的示例的文章。
但是,两个示例都通过首先使用GraphQL架构定义语言(下面是repo for Link 2的摘录)来构造其架构,以演示如何使用自定义指令来检查用户是否有权查询特定的字段(例如“评分”)。
require('dotenv').config();
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {
makeExecutableSchema
} = require('graphql-tools');
const {directiveResolvers} = require('./directives');
const {allProductsBySupplier, addProduct, product, suppliers} = require('./resolvers');
require('./auth');
const app = express();
const port = 8080;
const typeDefs = `
directive @isAuthenticated on QUERY | FIELD
directive @hasScope(scope: [String]) on QUERY | FIELD
type Product {
id: ID!
supplierId: ID!
sku: String
qty: Int
price: Int
parrot: String
rating: Int @hasScope(scope: ["read:rating"])
}
type Supplier {
id: ID!
name: String!
}
input ProductInput {
supplierId: ID!
sku: String!
qty: Int!
price: Int!
parrot: String!
rating: Int!
}
type Query {
allProductsBySupplier: [Product] @isAuthenticated
product: Product @isAuthenticated
suppliers: [Supplier]
}
type Mutation {
addProduct(input: ProductInput!): Product @hasScope(scope: ["add:product"])
}
`;
const resolvers = {
Query: {
allProductsBySupplier,
product,
suppliers
},
Mutation: {
addProduct
}
};
const schema = makeExecutableSchema({
typeDefs,
resolvers,
directiveResolvers
});
app.use(
'/graphql',
graphqlHTTP({
schema,
graphiql: true
})
);
app.listen(port);
console.log(`server running on localhost:${port}`);
我没有使用GraphQL模式定义语言来构造我的API,如下所示。以下代码段已从official graphql docs中提取。
var express = require('express');
var graphqlHTTP = require('express-graphql');
var graphql = require('graphql');
// Maps id to User object
var fakeDatabase = {
'a': {
id: 'a',
name: 'alice',
},
'b': {
id: 'b',
name: 'bob',
},
};
// Define the User type
var userType = new graphql.GraphQLObjectType({
name: 'User',
fields: {
id: { type: graphql.GraphQLString },
name: { type: graphql.GraphQLString },
}
});
// Define the Query type
var queryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: {
user: {
type: userType,
// `args` describes the arguments that the `user` query accepts
args: {
id: { type: graphql.GraphQLString }
},
resolve: function (_, {id}) {
return fakeDatabase[id];
}
}
}
});
var schema = new graphql.GraphQLSchema({query: queryType});
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
如果我在不使用GraphQL架构定义语言构建了架构的情况下,如何创建自定义指令来检查用户是否有权查询特定字段?