如何对 graphql 解析器实施保护

Posted

技术标签:

【中文标题】如何对 graphql 解析器实施保护【英文标题】:How a guard can be implemented to a graphql resolver 【发布时间】:2019-09-28 22:57:13 【问题描述】:

我是 graphql 的新手,我正在尝试在我的项目中集成身份验证/授权系统。我在 Medium 上找到了一个示例,但我不明白警卫如何与解析器通信。如果有人知道,我将不胜感激。

import  ApolloServer  from 'apollo-server';
import gql from 'graphql-tag';
import  tradeTokenForUser  from './auth-helpers';

const HEADER_NAME = 'authorization';

const typeDefs = gql`
  type Query 
     me: User
     serverTime: String
  
  type User 
     id: ID!
     username: String!
  
`;

const resolvers = 
   Query: 
      me: authenticated((root, args, context) => context.currentUser), 
      serverTime: () => new Date(),
   ,
   User: 
      id: user => user._id,
      username: user => user.username,
   ,
;

const server = new ApolloServer(
   typeDefs,
   resolvers,
   context: async ( req ) => 
      let authToken = null;
      let currentUser = null;

       try 
          authToken = req.headers[HEADER_NAME];

          if (authToken) 
               currentUser = await tradeTokenForUser(authToken);
          
        catch (e) 
          console.warn(`Unable to authenticate using auth token: $authToken`);
       

      return 
          authToken,
          currentUser,
      ;
   ,
);

server.listen().then(( url ) => 
  console.log(`????  Server ready at $url`);
);
export const authenticated = next => (root, args, context, info) => 
  if (!context.currentUser) 
      throw new Error(`Unauthenticated!`);
  

  return next(root, args, context, info);
;

我不明白“下一个”参数的作用以及为什么在调用这个守卫时作为参数我必须返回一个值?

【问题讨论】:

【参考方案1】:

authenticated 是使代码干燥的高阶函数。 next 是用作谓词的回调。

这是一种 DRYer 的书写方式:

...
me: (root, args, context) => 
  if (!context.currentUser) 
      throw new Error(`Unauthenticated!`);
  

  return context.currentUser;
)
...

【讨论】:

以上是关于如何对 graphql 解析器实施保护的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 apollo / graphql 实现节点查询解析器

从 graphql yoga 返回状态码

使用 GraphQL 的 Angular2 服务和路由解析器

GraphQL。如何编写解析器

如何模拟 mongodb 以进行单元测试 graphql 解析器

GraphQL 解析器问题