权限控制
业务需求:查看用户列表接口(管理员才能使用)、更新用户信息接口(当前对应用户才能调用)
这时候需要需要加入中间件来实现权限控制:
这时候咱们需要学习了解下:AccessToken jwt
AccessToken jwt
课前学习了解
JSON Web Token 入门教程
http://www.ruanyifeng.com/blo…
基于 jsonwebtoken(JWT)的 web 认证 (Node 版实现)
https://segmentfault.com/a/11…
node-jsonwebtoken
https://github.com/auth0/node…
本文中使用了 node-jsonwebtoken@7.2.1 插件
现将 token 服务逻辑代码附上
/**
* token 服务
* add by boomer 2019-05-03 21:57:11
*/
var Promise = require("bluebird");
var config = require('config-lite'); // 配置
var jwt = require('jsonwebtoken'); //json token
module.exports = {
/**
* 设置 token 创建 token
*/
setToken: function(payload) {// var expiresIn = Math.floor(Date.now() / 1000) + (1 * 60); // var expiresIn = '24h';
var expiresIn = Date.now() + 3600000 * 24;//24 小时后
var token = jwt.sign(payload, config.token.secretOrPrivateKey, {expiresIn: expiresIn, // 设置过期时间});
return {
token: token,
expiresIn: expiresIn,
};
},
/**
* 验证 token 是否正确:传入当前 token 和当前用户 uuid
*/
verifyToken: function(token, userUuid){return new Promise(function(resolve, reject) {jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) {if (tokenData && tokenData.uuid == userUuid) {resolve('ok');
}else{reject('fail');
}
});
});
},
/**
* 路由验证 token
*/
verifyRouterToken: function(req, res, next, isAdmin) {
//accesstoken 被自动转小写了
var token = req.headers.accesstoken;
if (!token) { // 如果没有 token,则返回错误
res.json({code: "401",});
return;
} else { // 验证 token
jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) { // 只有在 token 正确时 tokenData 有值
if (err) {
res.json({code: "402",});
return;
} else {
// 验证是否为管理员
if (isAdmin && !tokenData.isAdmin) {
res.json({code: "403",});
return;
} else if (!isAdmin && tokenData.uuid && !tokenData.isAdmin) {
// 验证 userUuid 避免普通用户登录修改其他人资料
var userUuid = (req.body || req.query || req.params)['userUuid'];
if (userUuid && userUuid != tokenData.uuid) {
res.json({code: "403",});
return;
} else {next();
}
} else {next();
}
}
});
}
},
/**
* 清除 token
*/
delToken: function(token) {if (!token) {return 'delTokenFail';} else {jwt.decode(token);
return 'delTokenSuccess';
}
},
};
accessToken 一般在登录 / 注册成功时获取 然后缓存到本地,每次前端请求时将有效的 accessToken 放到 headers 中,然后请求到后端,后端再通过校验 token 中间件做权限拦截,校验通过后才能执行后面的业务逻辑(这块后面写前端时补充)
现在说下,后端通过上面 tokenService.setToken 方法 生成 AccessToken 的代码: