如何创建自定义指令以保护GraphQL API?

时间:2018-10-01 11:32:32

标签: authorization graphql

我想使用自定义指令来保护我的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架构定义语言构建了架构的情况下,如何创建自定义指令来检查用户是否有权查询特定字段?

0 个答案:

没有答案