nodejs+express中利用中间件提高代码复用

在用nodejs+express+mysql做后台时,有很多涉及到用户信息的请求都要先判断请求中的token(用户名+时间戳+随机数采用sha1加密得到的随机字符串)是否有效。

一开始是在每个请求的处理中都加入了对token的判断。(写了n遍,脑袋抽了)

代码如下:

//修改项目的状态
router.post('/change-project',validToken,function(req,res,next){
    var db = req.db;
    var token = req.query.token;
    var id = req.query.id;
    var projectStatus = req.query.status;
    var data = {
        status : false,
        message : ""
    }
    db.getConnection(function(err,conn){
        if(err){
            sendData(req,res,next,conn,err);
        }else {
            db.query('SELECT * FROM user WHERE user_token = '+token+'',function(err,row){//判断token是否有效
                if(err){
                    sendData(req,res,next,conn,err);
                }else{
                    if(row.length == 0){
                        sendData(req,res,next,conn,"请登录");//无效返回错误信息
                    }else {//若token有效修改状态
                        db.query('UPDATE project SET project_status = ' + projectStatus + ' WHERE project_id = ' + id + '', function (err, row) {
                            if (err) {
                                sendData(req, res, next, conn, err);
                            } else {
                                data.message = (row.affectedRows == 1) ? "修改成功" : "修改失败";
                                data.status = (row.affectedRows == 1) ? true : false;
                                res.send({'data': data});
                                conn.release();
                            }
                        })
                    }
                }
            })

        }
    })
})


涉及到token验证的地方比较冗余,因为在每个需要验证的函数里都要写一遍。

所以讲验证token的这部分提出来变成一个中间件

代码如下:

function validToken(req, res, next){
    var db = req.db;
    var userToken = req.query.token;
    db.getConnection(function(err,conn){
        if(err){
            sendData(req,res,next,conn,err);
        }else{
            db.query('SELECT * FROM user WHERE user_token = '+userToken+'',function(err,row){
                if(err){
                    sendData(req,res,next,conn,err);
                }else{
                    if(row.length == 0){
                        sendData(req,res,next,conn,"请登录");
                    }else{
                        next();
                    }
                }
            })
        }
    })
}
//出错时返回一个data对象
function sendData(req,res,next ,conn,message){
    var data = {
        message : "", //出错信息
        status : false //状态
    }
    data.message = message;
    conn.release();
    res.send({"data" : data});

}

然后将这个中间件应用到对应的路由中,

这样第一个路由就变成了,下面的样纸:

//修改项目的状态
router.post('/change-project',validToken,function(req,res,next){
    var db = req.db;
    var token = req.query.token;
    var id = req.query.id;
    var projectStatus = req.query.status;
    var data = {
        status : false,
        message : ""
    }
    db.getConnection(function(err,conn){
        if(err){
            sendData(req,res,next,conn,err);
        }else {
            db.query('UPDATE project SET project_status = ' + projectStatus + ' WHERE project_id = ' + id + '', function (err, row) {
                if (err) {
                    sendData(req, res, next, conn, err);
                } else {
                    data.message = (row.affectedRows == 1) ? "修改成功" : "修改失败";
                    data.status = (row.affectedRows == 1) ? true : false;
                    res.send({'data': data});
                    conn.release();
                }
            })    
        }
    })
})

这样别的需要验证token就无需重复在写,可以直接重用。

其实,关于查询数据库时的一层层嵌套(if(err) 错误处理 else 查询)也可以通过中间件解决。

具体可以看这篇博客:http://www.360doc.com/content/14/1003/20/14106735_414210206.shtml

睡养颜觉去了~~

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。