Express + JWT 排除某些路线

Posted

技术标签:

【中文标题】Express + JWT 排除某些路线【英文标题】:Express + JWT exclude certain routes 【发布时间】:2018-05-20 03:15:05 【问题描述】:

我有一个使用expressjsonwebtoken 运行的Node 应用程序。在每次请求 api 调用检查 jsonwebtoken 之前,我都进行了检查。我已经手动排除了如下路线。有没有更好的方法来排除一些路线?我该怎么做?

import * as express from 'express';
import * as jwt from 'jsonwebtoken';

import UserCtrl from './controllers/user';

export default function setRoutes(app) 

  const router = express.Router();

  // route middleware to verify a token
  router.use(function (req, res, next) 
    if ((req.method == 'POST' || req.method == 'OPTIONS') && (req.url == '/user' || req.url == '/login' || req.url == '/user/activate')) 
      next();
     else 
      // check header or url parameters or post parameters for token
      var token = req.headers.authorization;
      // decode token
      if (token) 
        // verifies secret and checks exp
        jwt.verify(token, process.env.SECRET_TOKEN, function (err, decoded) 
          if (err) 
            return res.status(401).send(
              success: false,
              message: 'Sign in to continue.'
            );
           else 
            // if everything is good, save to request for use in other routes
            next();
          
        );
       else 
        // if there is no token
        // return an error
        return res.status(401).send(
          success: false,
          message: 'Sign in to continue.'
        );
      
    
  );

  const userCtrl = new UserCtrl();

  router.route('/login').post(userCtrl.login);
  router.route('/user/activate').post(userCtrl.activate);
  router.route('/users').get(userCtrl.getAll);
  router.route('/users/count').get(userCtrl.count);
  router.route('/user').post(userCtrl.signup);
  router.route('/user/:id').get(userCtrl.get);
  router.route('/user/:id').put(userCtrl.update);
  router.route('/user/:id').delete(userCtrl.delete);

  app.use('/api/v1', router);

【问题讨论】:

【参考方案1】:

您可以提取函数(验证令牌的函数)并将其用作路由器中特定路由的中间件。这样您就不必在函数内指定需要登录的路由。

像这样:

function isLoggedIn(req, res, next) 
    // check header or url parameters or post parameters for token
    var token = req.headers.authorization;
    // decode token
    if (token) 
        // verifies secret and checks exp
        jwt.verify(token, process.env.SECRET_TOKEN, function(err, decoded) 
            if (err) 
                return res.status(401).send(
                    success: false,
                    message: 'Sign in to continue.'
                );
             else 
                // if everything is good, save to request for use in other routes
                next();
            
        );
     else 
        // if there is no token
        // return an error
        return res.status(401).send(
            success: false,
            message: 'Sign in to continue.'
        );
    


const userCtrl = new UserCtrl();

// Routes that require no login
router.post('/login', userCtrl.login);
router.get('/users', userCtrl.getAll);
router.post('/user/activate', userCtrl.activate);

// Routes that require login
router.get('/users/count', isLoggedIn, userCtrl.count);
router.post('/user', isLoggedIn, userCtrl.signup);
router.get('/user/:id', isLoggedIn, userCtrl.get);
router.put('/user/:id', isLoggedIn, userCtrl.update);
router.delete('/user/:id', isLoggedIn, userCtrl.delete);

app.use('/api/v1', router);

你可以阅读更多关于Express Middlewares here的信息。

【讨论】:

【参考方案2】:

你可以这样做

app.use(
  jwt( secret, algorithms: ['HS256'] ).unless( path: ['/foo/bar'] ),
);

【讨论】:

以上是关于Express + JWT 排除某些路线的主要内容,如果未能解决你的问题,请参考以下文章

Node.js和Express排除路由形式JWT中间件

使用 GraphQL 和 jwt-express 绕过 JWT

使用 JWT 保护 Express 路线

JWT 和 express-JWT 有问题

如何才能在缺失路线上将Express.js变为404?

如何使用 JWT 在 Express 中验证单个路由(无代码重复)的多种类型用户的身份验证令牌?