在用nodejs+express+mysql做后台时,有很多涉及到用户信息的请求都要先判断请求中的token(用户名+时间戳+随机数采用sha1加密得到的随机字符串)是否有效。
一开始是在每个请求的处理中都加入了对token的判断。(写了n遍,脑袋抽了)
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//修改项目的状态
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的这部分提出来变成一个中间件
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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});
}
|
然后将这个中间件应用到对应的路由中,
这样第一个路由就变成了,下面的样纸:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//修改项目的状态
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 查询)也可以通过中间件解决。