【问题标题】:Handling token based authorization in Node Js在 Node Js 中处理基于令牌的授权
【发布时间】:2019-06-01 00:14:35
【问题描述】:

我是 Node Js 的新手。之前,我使用 Laravel API。在 Laravel 中,我使用保存在数据库中的令牌来处理 Endpoints 以使用某些端点。例如:localhost:3000/api/users/getall?token=1234。如果没有令牌通过,API 会显示Unauthorized access and no token provided。如果令牌无效,则系统将显示Invalid token。这样,如何使用保存在 Mongo 数据库中的令牌验证端点?

用户模型

var bcrypt = require('bcryptjs');
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema(
{
    fname : {type: String, required: true, max: 25, trim: false},
    uname : {type: String, required: true, max: 25, trim: false},
    password : {type: String, required: true},
    token : {type: String, required: true},
    role: {type: String, required: true}, //0 - admin, 1 - counter
},
{
    timestamps:true
});

mongoose.model('User', userSchema);
module.exports = mongoose.model('User');

以下用户 getAll 端点只能由管理员访问

getAll 端点

router.get("/", function (req, res, next)
{
    User.find()
    .select('fname uname')
    .exec()
    .then(docs => {
        return res.send(setting.status("User details retrieval successfully", true, docs))
    .catch(err => {
        return res.send(setting.status("Error in retrieving user details",false, err))
    });
    });
});

})

上面的 getAll 路由现在也可以被管理员和计数器访问。而且它不检查数据库中的令牌(即:可以在没有令牌的情况下访问)。

如何使用令牌检查和验证?

【问题讨论】:

  • 你熟悉中间件吗?
  • 不,我是 node js 新手

标签: node.js token


【解决方案1】:

在做任何事情之前,从查询参数中获取令牌并验证它。如果它无效,只需发送一个“401 Unauthorized”状态,或任何你喜欢的响应。

router.get("/", function (req, res, next) {      
  const token = req.query.token
  if (!isValid(token)) return res.status(401).end()

  User.find()
    .select('fname uname')
    .exec()
    .then(docs => {
      return res.send(setting.status("User details retrieval successfully", true, docs))
    })
    .catch(err => {
      return res.send(setting.status("Error in retrieving user details",false, err))
    });
})

确保您明确返回,否则执行将继续。或者只使用if-else 声明。

【讨论】:

  • isValid(token)if 声明中是什么?我该如何检查?
  • 您应该拥有isValid 的实现。我不知道你用的是什么类型的令牌。
  • 我正在使用jwt 令牌
  • 而且我认为它不会检查role
  • 在这种情况下,如果您只对它有效时感兴趣,我建议使用 jsonwebtoken 包和 verify 方法
【解决方案2】:

您可以使用中间件来验证请求。在 server.js 上

//validate requests
app.use ('/', function (req, res, next) {
  if (
    // except the public requests (for login ...)
    req.originalUrl.indexOf ('/public') > -1
  ) {
    next ();
  } else {
    if (
      // Compare with your token
      req.query &&
      req.query.hasOwnProperty ('access_token') &&
      req.query.access_token === 'YOUR_TOKEN'
    ) {
      next ();
    } else {
      // STOP
      return res.json ({
        success: false,
        message: 'Failed to authenticate.',
      });
    }
  }
});

希望对您有所帮助。

【讨论】:

  • 两个if 语句中的next() 是什么?
  • 如何验证role
  • 如果找不到您要找的内容,请搜索您的下一个问题或创建一个新问题。
  • 关于next()和中间件的理解可以阅读expressjs.com/en/guide/using-middleware.html
最近更新 更多