【问题标题】:Secure GraphQL queries with express js, passport s使用 express js、passport s 保护 GraphQL 查询
【发布时间】:2017-08-10 16:35:21
【问题描述】:

我已经开始在我的 express js 项目中使用 graphql,但我想知道如何保护我的一些 GraphQL 查询。 以前我为此使用了护照 js(JWT),效果很好。保护路线真的很容易,但是使用 graphql(express-graphql) 我找不到任何解决方案。 此外,最好有某种基于角色的解决方案来保护特定领域。有什么好的教程如何保护 graphQL 吗?

【问题讨论】:

    标签: javascript express graphql


    【解决方案1】:

    最后我检查了那里没有任何真正好的教程来展示如何保护 GraphQL 端点。但是,社区(GraphQL 和 Apollo 松弛通道)的共识是,最好将身份验证与 GraphQL 分开(例如使用 Passport)并在您的解析函数中进行授权,可能通过使用一些基于角色的身份验证来装饰它们。

    目前我可以提供的最佳链接是this post 我不久前写过关于使用 Passport.js 为 GraphQL 端点设置身份验证的文章。希望对你有帮助!

    我目前正在使用 Apollo 编写 React + Node.js 的全栈 GraphQL 教程,我计划为此做一些关于 Auth 的工作。我会在发布后尽快更新此答案。

    【讨论】:

      【解决方案2】:

      我目前正在评估通过 express、passport 和 jwt 对解析器进行授权的潜力。它尚未经过全面测试,但可以正常工作。

      为此,您至少需要在上下文中传递请求:

      const graphql = graphqlExpress((req, res) => {
        return ({
          schema,
          rootValue: resolver,
          // For query authorization. Ideally, Passport will handle all requests and authenticate
          // each one for the current user. The queries will fetch data exclusively related to that user.
          context: { req, res },
        });
      });
      // The api
      app.use('/api', graphql);
      

      在这种情况下,我承诺了护照认证:

      const auth = (req, res) => new Promise((resolve, reject) => {
        passport.authenticate('jwt', { session: false }, (err, user) => {
          if (err) reject(err);
          if (user) resolve(user);
          else reject('Unauthorized');
        })(req, res);
      });
      
      const resolver = {
        users: (root, ctx) => auth(ctx.req, ctx.res)
          .then(() => User.find({}, (err, res) => res))
          .catch((err) => {
            throw new Error(err);
          }),
      };
      

      由于没有太多关于如何涵盖这一点的示例,我一直在努力让它变得简单,但我认为我做得很好。

      这里是我用来达到这一点的资源:

      【讨论】:

      • ElPepe 干得好,大多数帖子都以更清晰的方式做到这一点
      • 这正是我想要的。非常感谢!
      【解决方案3】:

      为了纠正错误,我修改了如下代码。

      const getUser = (req: Express.Request, res: Express.Response) => 
        new Promise((resolve, reject) => {
          passport.authenticate('jwt', {session: false}, (err, payload, info) => {
            if (err) reject(info)
            if (payload) resolve(payload)
            else reject(info)
          })(req, res)   
      })
      
      
      const getApolloServer = async () => {
        return new ApolloServer({
          schema: await buildSchema({
            resolvers: [] // Your resolvers
          }),
          context: async ({ req, res }) => {
            try {
                const user = await getUser(req, res)
                return { user }
              } catch(err: any) {
                console.log(err)
                res.status(401).json(err.message)
              }
           },
           introspection: true,
           playground: true,
         })
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-11
        • 2014-02-17
        • 2019-07-14
        • 2018-01-27
        • 2019-06-30
        • 2021-10-19
        • 2018-11-10
        • 2021-06-23
        • 2019-12-25
        相关资源
        最近更新 更多