Node.js 在全局范围内路由之前拦截NodeJ(Express)上的头

Node.js 在全局范围内路由之前拦截NodeJ(Express)上的头,node.js,express,Node.js,Express,我的server.js上有这样的代码 var session = { v1: require('./routes/v1/session') } app.post('/v1/session/login', session.v1.login); app.get('/v1/session/logout/:uuid', session.v1.logout); var modify = { v1: require('./routes/v1/modify') } app.put('/v1/m

我的server.js上有这样的代码

var session = {
    v1: require('./routes/v1/session')
}
app.post('/v1/session/login', session.v1.login);
app.get('/v1/session/logout/:uuid', session.v1.logout);

var modify = {
   v1: require('./routes/v1/modify')
}
app.put('/v1/modify/:uuid/password', modify.v1.password);
app.put('/v1/modify/:uuid/mobile', modify.v1.mobile);
app.put('/v1/modify/:uuid/email', modify.v1.email);
以上所有情况下,我都会发送一个带有令牌的授权头,登录除外,因为登录后您将收到令牌

因此,在我的所有路由中,我需要调用一个例程来验证令牌,然后执行操作。像这样:

exports.logout = function (req, res) {
   var auth = req.headers.authorization;
   global.utils.validateToken(auth).then(function(uuid) {  
       // Code here
   }
}
但我非常确信有更好的方法可以做到这一点。类似于在调用路由器之前对每个服务器请求执行授权检查

这可能吗?如果是:我可以定义例外情况吗(例如,在登录的情况下,我不需要检查授权)


谢谢

有多种方法可以做到这一点,我将介绍三种方法,你可以选择任何你喜欢的方法

因此,基本上,您需要创建一个不应在登录时调用的中间件

您将要做的是,制作一个中间件,如下所示:

var middleware = {
  authTokenValidator = function(req, res, next) {
    var auth = req.headers.authorization;
    global.utils.validateToken(auth).then(function(uuid) {
      // Token Valid Code here
      next();
    }).catch(function(err) {
      // Token failure handling code here
      res.status(401).json(err);
    })
  }
}
现在,您可以通过两种方式使用此中间件: 首先是在需要的地方为路由使用中间件。。如下文所述:

var session = {
    v1: require('./routes/v1/session')
}
// Skipped for login
app.post('/v1/session/login', session.v1.login);
app.get('/v1/session/logout/:uuid', middleware.authTokenValidator, session.v1.logout);

var modify = {
   v1: require('./routes/v1/modify')
}
app.put('/v1/modify/:uuid/password', middleware.authTokenValidator, modify.v1.password);
app.put('/v1/modify/:uuid/mobile', middleware.authTokenValidator, modify.v1.mobile);
app.put('/v1/modify/:uuid/email', middleware.authTokenValidator, modify.v1.email);
所以,基本上使用next函数可以将任意数量的函数作为中间件传递,并调用next中间件函数

第二种方法是全局传递中间件并处理异常,如登录URL: 定义中间件上方所有不应通过中间件的路由,以及中间件下方的其他路由,代码如下,以供参考:

var session = {
    v1: require('./routes/v1/session')
}
// Skipped for login
app.post('/v1/session/login', session.v1.login);

// All the requests except the above path will go throgh this middleware
app.use(middleware.authTokenValidator)

app.get('/v1/session/logout/:uuid', session.v1.logout);

var modify = {
   v1: require('./routes/v1/modify')
}
app.put('/v1/modify/:uuid/password', modify.v1.password);
app.put('/v1/modify/:uuid/mobile', modify.v1.mobile);
app.put('/v1/modify/:uuid/email', modify.v1.email);
第三种方法与第二种方法类似,只是在中间件中检查请求路径并跳过它,这是不可取的

var middleware = {
  authTokenValidator = function(req, res, next) {
    var no_validate_path = ['/v1/session/login']
    // Skipping the login path here
    if (no_validate_path.indexOf(req.path) >= 0) {
      next()
    } else {
      var auth = req.headers.authorization;
      global.utils.validateToken(auth).then(function(uuid) {
        // Token Valid Code here
        next();
      }).catch(function(err) {
        // Token failure handling code here
        res.status(401).json(err);
      })
    }

  }
}
您的路线代码为:

//Adding middleware for all the paths
app.use(middleware.authTokenValidator)

var session = {
  v1: require('./routes/v1/session')
}
app.post('/v1/session/login', session.v1.login);
app.get('/v1/session/logout/:uuid', session.v1.logout);
var modify = {
  v1: require('./routes/v1/modify')
}
app.put('/v1/modify/:uuid/password', modify.v1.password);
app.put('/v1/modify/:uuid/mobile', modify.v1.mobile);
app.put('/v1/modify/:uuid/email', modify.v1.email);
有关中间件的参考资料