【问题标题】:middleware that run before any routes在任何路由之前运行的中间件
【发布时间】:2016-03-11 02:55:53
【问题描述】:

我正在尝试进行基于令牌的身份验证。在任何请求发生之前,我都坚持运行身份验证。例如下面的代码是获取用户,但是一个中间件应该检查​​请求是否有有效的令牌。

app.js

var user = require('./controllers/user');
app.use('/api', user);

user.js

var express = require('express');
var router = express.Router(); 

router.get('/user', function(req, res) {
  User.find({}, function(err, users) {
    res.json(users);
  });
});

module.exports = router;

我有 here 的逻辑,但我不知道该放在哪里。

【问题讨论】:

  • 把你的中间件作为router.get()方法的第二个参数。
  • @GökayGürcan 可以举个例子吗?

标签: javascript node.js express npm


【解决方案1】:

在您的 app.js 中,使用 express 的 app.use()任何路由之前注册令牌身份验证中间件。

这样,每次调用 after 定义的路由时都会执行令牌认证。基本上 app.use(authentication) 和 app.use('*', authentication) 是一样的,这意味着中间件是针对所有域执行的,而不仅仅是 '/api'。

auth.js

module.exports = function(req, res, next) {

    // check header or url parameters or post parameters for token
    var token = req.body.token || req.param('token') || req.headers['x-access-token'];

    // decode token
    if (token) {

        // verifies secret and checks exp
        jwt.verify(token, app.get('superSecret'), function(err, decoded) {          
            if (err) {
                return res.json({ success: false, message: 'Failed to authenticate token.' });      
            } else {
                // if everything is good, save to request for use in other routes
                req.decoded = decoded;  
                next();
            }
        });

    } else {

        // if there is no token
        // return an error
        return res.status(403).send({ 
            success: false, 
            message: 'No token provided.'
        });

    }

};

app.js

var express = require("express");
var app = module.exports = express();

// put the middleware before any routes in app.use()
var authentication = require("./middleware/auth");
app.use(authentication);

var user = require('./controllers/user');
app.use('/api', user);

如果您希望仅对“/api”路由进行令牌检查,则仅针对该路由定义身份验证

app.use('/api', authentication, user);

app.use() 按给定顺序运行作为参数给出的函数。

【讨论】:

    【解决方案2】:

    把你的中间件放在一切之前:)

    var app = express();
    
    function myCustomMiddleware(req, res, next) {
      if(/**something we need **/) {
        req.haveWhatWeNeed = true;
      }
      
      return next();
    }
    
    app
    .use(myCustomMiddleware)
    .get(/*** everything you want***/)
    ;

    【讨论】:

    • 想象一下我必须在每条路线中都包含它
    • 不,你不知道,考虑到 express 的工作原理,这个中间件总是被调用。简单地把它放在任何其他中间件之前......
    【解决方案3】:

    您可以在定义任何路由之前定义中间件,以确保它们在被路由处理之前得到执行。

    【讨论】:

      【解决方案4】:

      我从您的问题中了解到,在执行路由代码之前,您需要进行中间件检查。

          var middlewareFunction = function(req, res, next) {
      
              // check header or url parameters or post parameters for token
              var token = req.body.token || req.param('token') || req.headers['x-access-token'];
      
              // decode token
              if (token) {
      
                  // verifies secret and checks exp
                  jwt.verify(token, app.get('superSecret'), function(err, decoded) {          
                      if (err) {
                          return res.json({ success: false, message: 'Failed to authenticate token.' });      
                      } else {
                          // if everything is good, save to request for use in other routes
                          req.decoded = decoded;  
                          next();
                      }
                  });
      
              } else {
      
                  // if there is no token
                  // return an error
                  return res.status(403).send({ 
                      success: false, 
                      message: 'No token provided.'
                  });
      
              }
      }
      

      像这样创建一个中间件函数,并在你的路由中添加这个函数..

      var express = require('express');
      var router = express.Router(); 
      
      router.get('/user', middlewareFunction, function(req, res, next) {
        User.find({}, function(err, users) {
          res.json(users);
        });
      });
      
      module.exports = router;
      

      希望这能解决您的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        • 1970-01-01
        • 2017-05-15
        • 1970-01-01
        • 2019-11-28
        • 2015-09-28
        • 1970-01-01
        相关资源
        最近更新 更多