在 Express 和 NodeJ 上保护路由

Posted

技术标签:

【中文标题】在 Express 和 NodeJ 上保护路由【英文标题】:Securing routes on Express and NodeJs 【发布时间】:2017-09-19 02:11:45 【问题描述】:

我正在寻找“限制”特定路线的最佳方式,我将用一个例子来解释它:

我有两个用户:

-user1 id:123

-user2 id:456

客户端(角度):

//LOGGED AS USER 123
$http.post('www.domain.com/api/user/123')
.then(function (data) 
  // here I should receive the data from user 123
)

上面的代码很容易做到,但我想只为用户 123 限制此端点(从服务器端)。如果用户 456 尝试获取该端点,则应该被踢。示例:

//LOGGED AS USER 456
$http.post('www.domain.com/api/user/123')
.then(function (data) 
  // should return error (forbidden resource)
)

如您所见,如果您以用户 456 身份登录,您可以从“api/user/123”获取数据,但您可以从“api/user/456”获取数据

我想从服务器端解决这个问题

问题:

使用 Node/Express/JWT 的最佳方法是什么??

【问题讨论】:

只从服务器端处理它。 @TuanAnhTran,这是我的想法,但我不知道最好的方法是什么,最好使用 JWT、Node 和 Express 如果user-id 是某种前缀,您可以使用user-id 对jwt 进行签名,并编写一个中间件来检查api url 中的前缀并在一个地方执行逻辑。另外,也许使用guid 作为用户ID 以防止猜测?不过可能不值得:) 我认为这样的中间件 -> if(decode(jwt).id == id_to_get) //pass else // don't pass 但我不知道是否是最好的选择 【参考方案1】:

我会使用不同的 URL 设计。而不是拥有

www.domain.com/api/user/123

我会的

www.domain.com/api/user

并从随请求发送的身份验证令牌或会话 ID 中发现用户 ID。

我看到了很多源自在 URL 中指定身份的授权/安全错误。如果您考虑一下,它实际上是在复制用户 ID 参数,因为它在 URL 中出现一次,在身份验证令牌中出现一次。这种重复通常会导致授权逻辑与自身不同步的问题。

【讨论】:

【参考方案2】:

创建中间件/authorize.js

const fs = require('fs');
const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => 
    console.log('in!');
    let key = fs.readFileSync('rsa_2048_pub.pem');
    // If you are using default HMAC key the line above would be something like this:        
    // let key = process.env.JWT_SECRET // nodemon.json file needed for this to work

    try
        const token = req.headers.authorization.split(' ')[1]; //req.headers.token;
        console.log(token);
        var decoded = jwt.verify(token, key)
        console.log(decoded);

        // add validation code here...

        next();

    catch(err)
      return res.status(401).json(error: err, message: 'Invalid token.');
    
;

在 routes/users.js 你将导入你的中间件并有这样的东西:

const User = require('../models/user')
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const authorize = require('../middleware/authorize'); //import your middleware

// add your middleware call to your routes
router.route('/validate-token').get(authorize, function(req,res, next)
  console.log('out!');

  res.status(200).json(message: 'Valid token.');
);

您可以使用您的有效负载来存储userIdadmin : true/false 等信息,以在您的中间件中授权访问。

为了更完整的授权处理,我建议也使用授权 像 CASL 这样的包以及 JWT 策略。

【讨论】:

以上是关于在 Express 和 NodeJ 上保护路由的主要内容,如果未能解决你的问题,请参考以下文章

如何保护 express.js 中的路由?

Express中间件的应用-路由保护(登录限制)网站维护页面404

Node/Express 的 Passport 身份验证中间件 - 如何保护所有路由

什么是对 Express 4 路由器上的某些路由进行身份验证的更好方法?

受保护路由的 jest.mock express-jwt 中间件行为

访问受 EJS 保护的 JWT 路由