Graphql 图形ql+;apollo server express,如何处理express auth中间件中的auth错误?

Graphql 图形ql+;apollo server express,如何处理express auth中间件中的auth错误?,graphql,apollo-server,Graphql,Apollo Server,我不知道如何在authMiddleware函数中处理auth错误 这是我的authMiddleware函数,它具有传统的快速错误处理方式 const jwt = require('jsonwebtoken'); const { appConfig } = require('../config'); function authMiddleware(req, res, next) { let token; const parts = req.headers.authorization.sp

我不知道如何在authMiddleware函数中处理auth错误

这是我的
authMiddleware
函数,它具有传统的快速错误处理方式

const jwt = require('jsonwebtoken');
const { appConfig } = require('../config');

function authMiddleware(req, res, next) {
  let token;
  const parts = req.headers.authorization.split(' ');

  if (parts.length === 2) {
    const schema = parts[0];
    const credentials = parts[1];

    if (/^Bearer$/i.test(schema)) {
      token = credentials;
    } else {
      // throw new Error();
      next(new Error('credentials_bad_scheme: Format is Authorization: Bearer [token]'));
    }
  }

  try {
    const { user } = jwt.verify(token, appConfig.JWT_SCERET);
    req.user = user;
  } catch (error) {
    // console.log(error);
    next(error);
  }
  next();
}

exports.authMiddleware = authMiddleware;
但是使用阿波罗快捷服务器和graphql系统。传递到
next
函数的
错误
无法正常工作。这意味着当使用
graphql
工具堆栈时,
express
错误处理方式似乎不再有效

authMiddleware
中的
错误
将不会传递到下面的快速错误处理中间件

app.use((err, req, res) => {
  console.log('error handler: ', err);
});
如果我使用
返回res.status(401).json({code:1001,msg:'Authorization failed'})
在身份验证失败时抛出新错误('xxx')
。请求将永远停止在这里,这意味着永远不会转到
graphqlExpressHandler
。为了让请求转到
graphqlExpressHandler
,我唯一能做的就是使用
console.log
打印错误

而且除非方法或所需的证书属性,否则无法使用
express jwt
因为在使用graphql时,只有一个名为“/graphql”的路由。因此,除非/graphql route

解决这个问题的一种方法是:为
auth
制作restful api,并以传统方式处理它。为数据查询制作
graphql
api。

延迟回答,但可能会帮助面临相同问题的人

以下是我们解决问题的方法:

graphql+apollo server express仅公开
/graphql
路由,因此简单而好的方法是将身份验证端点公开为graphql变体,并在传递给
apollo server
实例的
上下文
函数中执行令牌验证(就像您的
authMiddleware
所做的那样)

例子:
  • 定义
    标记
    变异
  • //graphql.ts
    从“apollo server express”导入{gql};
    从“/handlers/authn_handler”导入AuthnHandler;
    导出常量typeDefs=gql`
    类型突变{
    令牌(用户名:String,密码:String):String
    }
    `
    const authnHandler=new authnHandler();
    导出常量解析程序={
    突变:{
    令牌:authnHandler.tokenResolver
    }
    };
    
  • 定义验证凭据并发出令牌的令牌冲突解决程序
  • //handlers/authn\u handler.ts
    从“apollo server express”导入{AuthenticationError};
    导出默认类AuthnHandler{
    
    公共异步令牌解析器(父级:任意、参数:任意、上下文:任意、信息:任意):apollo server
    文档中的Promise提供了这种实现方式的详细说明。

    您已经解决了这个问题吗?我也面临着这个问题。您可以在一个单独的函数中提取问题中的身份验证逻辑,该函数只需要一个标题。然后在“正常”中express routes您使用中间件来运行身份验证代码,但在Apollo中,您使用上下文创建来调用您的函数。
    // auth_middleware.ts
    const jwt = require('jsonwebtoken');
    const { appConfig } = require('../config');
    
    function authMiddleware({ req }) {
      let token;
      const parts = req.headers.authorization.split(' ');
    
      if (parts.length === 2) {
        const schema = parts[0];
        const credentials = parts[1];
    
        if (/^Bearer$/i.test(schema)) {
          token = credentials;
        } else {
          throw new Error();
        }
      }
    
      try {
        const { user } = jwt.verify(token, appConfig.JWT_SCERET);
        req.user = user;
      } catch (error) {
        throw new Error();
      }
      return { req };
    }
    
    exports.authMiddleware = authMiddleware;