使用passportJS进行Apollo GraphQL Server身份验证

时间:2018-03-09 16:23:41

标签: passport.js graphql apollo apollo-server

我试图在允许访问我的'/ graphql'端点之前验证用户。

根据关于设置上下文的apollo-server文档,我可以做这样的事情。

app.use(
  '/graphql',
  bodyParser.json(),
  graphqlExpress(req => {
    // Some sort of auth function
    const userForThisRequest = getUserFromRequest(req);

    return {
      schema: myGraphQLSchema,
      context: {
        user: userForThisRequest,
      },
      // other options here
    };
  }),
);

我试图在占位符中使用passportJS的authenticate()函数来处理“某种auth函数”,但我似乎无法理解如何利用我有权访问的'req'参数。我应该在bodyParser中间件之后还是在graphqlExpress方法中调用passport.authenticate()?

所以我的问题是如何在这种情况下使用passportJS的身份验证机制?另外,这是在Apollo-server上实现身份验证的最佳方式吗?

1 个答案:

答案 0 :(得分:3)

您可以通过几种不同的方式执行此操作 - 具体取决于您在身份验证失败时要发送回客户端的响应类型以及微调身份验证过程所需的数量。 / p>

Passport的authenticate功能实际上只是表达中间件,所以你可以这样做:

app.use(
  '/graphql',
  bodyParser.json(),
  authenticate(),
  graphqlExpress(req => ({
    schema: myGraphQLSchema,
    context: {
      user: getUserFromRequest(req),
    },
  }));
);
如果身份验证失败,

authenticate将发送一个401状态的响应(响应本身取决于您在护照策略中配置验证回调的方式)。这意味着如果身份验证失败,将永远不会调用Apollo服务器中间件。

或者,您可以避免使用authenticate并自行处理检查身份验证。这可以在解析器级别完成,或者通过使用graphql-tool的addSchemaLevelResolveFunction在所有解析器中完成。 从' graphql-tools'

导入{addSchemaLevelResolveFunction}
addSchemaLevelResolveFunction(executableSchema, (root, args, ctx, info) => {
  if (!ctx.user) throw new CustomAuthenticationError()
})

最大的区别是您的响应现在将返回200状态,并且将包含空数据属性和包含身份验证错误的错误数组。

当然,第二种方法还允许您微调您的身份验证逻辑 - 例如,如果您只希望将查询或突变的子集限制为仅对经过身份验证的用户可用。除此之外,我不知道两种方法是否都必须更好。