【问题标题】:Validating jwt token in router file验证路由器文件中的 jwt 令牌
【发布时间】:2020-02-22 12:48:28
【问题描述】:

我创建了一个在 mysql 数据库上执行一些查询的 Rest Api。该 api 是通过 oclif 构建的 cli a 访问的。我正在尝试在执行查询之前验证令牌。我想在同一个文件(routes.js)中进行验证。该文件如下所示:

module.exports = app => {
  const entry = require("../controlers/entry.controller.js");
  const sql = require("../models/db.js");
  const bcrypt = require('bcrypt');
  var express=require('express');

  // Retrieve a single Entry with Id
  var fs=require('fs');
  var privateKey = fs.readFileSync('private.key');
  var jwt=require('express-jwt');
  app.use(
    jwt({
      secret: privateKey,
      credentialsRequired: false,
      getToken: function fromHeaderOrQuerystring (req) {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
            return req.headers.authorization.split(' ')[1];
        } else if (req.query && req.query.token) {
          return req.query.token;
        }
        return null;
      }
    }));


  app.get("/entry/:Id", entry.findOne);

  app.post("/energy/api/Login", function(req,res){ 
        var jwt=require('jsonwebtoken');
        sql.query(`SELECT user,pass,quota,apikey,email FROM users WHERE user=?`,[req.query.username],(err,res1) => {
            //console.log(res1);
            const password=res1[0].pass;
            const e=res1[0].email;
            const a=res1[0].apikey;
            const q=res1[0].quota;
            const p=res1[0].privileges;
            if(bcrypt.compareSync(req.query.passw,password)){
                var jwt=require('jsonwebtoken');
                var privateKey = fs.readFileSync('private.key');
                var token = jwt.sign({user:req.query.user ,passw: req.query.passw,email: e, quota: q,apikey: a,privileges: p }, privateKey, { algorithm: 'HS256' });
                res.status(200).send(token);
            }
            else res.status(400).send("Bad Request");
        });

  });

在登录部分,我创建了令牌并将其返回给 CLI。然后 cli 执行如下操作:

axios.defaults.headers.common['X-OBSERVATORY-AUTH']="Bearer " + token;
    await cli.anykey();
    //create new user
    if (`${flags.newuser}` !== "undefined" && `${flags.passw}` !== "undefined" && `${flags.email}` !== "undefined" && `${flags.quota}` !== "undefined" ){
            let hash = bcrypt.hashSync(`${flags.passw}`,10);
            await axios.post('https://localhost:8765/energy/api/Admin/users?username=' +`${flags.newuser}` +'&passw=' + hash +'&email=' + `${flags.email}`  +'&quota=' + `${flags.quota}`);

    }

但是,当 routes.js 文件获取 post 命令时,它会像这样处理它:

app.put("/energy/api/Admin/users/:username",async function(req,res){        
            if (req.params.username !== "undefined" && req.query.email !== "undefined" && req.query.quota !== "undefined"){ 
                console.log(req.params.username);
                sql.query(`UPDATE users SET pass=?,email=?,quota=? WHERE user=?`,[req.query.passw,req.query.email,req.query.quota,req.params.username],(err,res) => {
                            if (err) {
                              console.log("error: ", err);
                              result(err, null);
                              return;
                            }
            });
            }
            res.send("Successful");
  });

我想添加一些中间件来验证令牌,并检查参数配额是否>0,是否将其减一。我该怎么做?

声明:这段代码是用node.js,express.js写的

【问题讨论】:

    标签: node.js api express command-line-interface


    【解决方案1】:

    首先你的代码没有模块化。 而且你必须编写路由中间件来保护路由而不是全局中间件

    我觉得这个项目可以帮助你理解jwt,express code(https://github.com/ahari884/simple-node-boilerplate) 请检查它,您将找到如何为 express 中的路由编写 jwt 身份验证

    【讨论】:

      【解决方案2】:

      你可以像这样编写一个专用的中间件:

      const jwt = require('jsonwebtoken');
      
      export async function verifyJWTToken(request, response, next) {
      /*
      * Normally JWTs are specified as Bearer Tokens.
      * Authorization Header will have something like 'Bearer <token>' 
      */
        const header = request.headers.authorization;
        if (header && header.startsWith('Bearer ')) { tokens
          const token = header.slice(7, header.length);
          const secret = process.env.JWT_SECRET;
          try {
            jwt.verify(token, secret);
            next();
          } catch (error) {
            next(new Error('Authentication Failed'));
          }
        } else {
          next(new Error('Missing Authentication Token'));
        }
      }
      
      

      然后,您可以通过在控制器功能之前提供中间件来保护您的路由:

      app.route('/users').get(verifyJWTToken, getUsers) //getUsers() is the controller function
      

      【讨论】:

      • 但是如何检查令牌的参数?
      • jwt.verify() 为您提供令牌详细信息。您可以将其保存为 const,然后您可以使用数据执行操作。
      猜你喜欢
      • 2020-11-17
      • 2020-11-18
      • 2019-07-20
      • 2019-06-23
      • 2018-08-30
      • 2017-07-27
      • 2019-10-20
      • 2016-01-17
      • 1970-01-01
      相关资源
      最近更新 更多