【问题标题】:Apollo GraphQL Server authentication with passportJSApollo GraphQL Server 使用 passportJS 进行身份验证
【发布时间】:2018-08-18 06:40:48
【问题描述】:

我正在尝试在允许访问我的“/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() 函数来表示“某种身份验证函数”,但我似乎无法理解如何使用我可以访问的 'req' 参数。我应该在 bodyParser 中间件之后还是在 graphqlExpress 方法内部调用 passport.authenticate()?

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

【问题讨论】:

    标签: passport.js graphql apollo apollo-server


    【解决方案1】:

    有几种不同的方法可以做到这一点 - 取决于您希望在身份验证失败时发送回客户端的响应类型以及您需要微调身份验证过程的程度。

    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 状态,并且将包含一个空数据属性和一个包含身份验证错误的错误数组。

    当然,第二种方法还可以让您微调您的身份验证逻辑——例如,如果您只想将查询或突变的子集限制为仅对经过身份验证的用户可用。除此之外,我不知道这两种方法是否一定更好。

    【讨论】:

      猜你喜欢
      • 2018-06-22
      • 2019-02-25
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 2018-05-23
      • 2020-08-17
      • 2014-12-19
      相关资源
      最近更新 更多