转载文章 http://mssn.midea.com/ask/?/article/189
基于jwt的一种权限验证思路
整体思路
- 登录后用jwt将带有level等级的用户信息生成token返回给前端
- 前端拿到token存进sessionstorage或者localstorage中,以后每次请求都将token以请求头authorization的形式传出去
- 服务端配置好API接口的访问权限,如level的等级,是否登录才能访问,并写好对应的控制器,再写一个过滤中间件
- 每一个请求都会经过过滤中间件,验证API接口的权限,通过才next(),否则就返回失败信息
API接口的配置例子
module.exports = [
{ "method": "post", "url": "/user/register", "noAuth": [], "needLogin" : false },
{ "method": "post", "url": "/user/login", "noAuth": [], "needLogin" : false },
{ "method": "patch", "url": "/user/avatar", "noAuth": [1], "needLogin" : false },
{ "method": "get", "url": "/user/getUser/:id", "noAuth": [], "needLogin" : true }
]
中间件写法
let log = require('../middlewares/log')
const api = require('../config/api')
const { createHash, createToken, verifyToken } = require('../common')
function permission(noAuth) {
return async function (ctx, next) {
try {
let token = (ctx.request.headers)['authorization'];
if (!token) { // 没带token
ctx.status = 403;
return ctx.body = { status: 'fail', data: 'token no found' };
} else { // 带了token
let result = verifyToken(token);
if (result == false) { // 无效的token
ctx.status = 401;
return ctx.body = { status: 'fail', data: '无效的token' };
} else { // token有效
if (noAuth.indexOf(result.identify) != -1) { // 权限在不能继续访问
ctx.status = 403;
return ctx.body = { status: 'fail', data: '权限不够' };
} else { // 权限可以访问
let newToken = createToken({ _id: result._id, name: result.name, identify: result.identify });
ctx.set('Authorization', newToken);
return next();
}
}
}
} catch (e) {
return ctx.body = { status: 'fail', data: e.message, }
}
}
}
module.exports = async function (app, router) {
try {
api.forEach((item, index, array) => {
let arr = item.url.split('/');
let controller = require('../controllers/' + arr[1]);
if (item.noAuth.length == 0 && item.needLogin == false) {
router[item.method](item.url, controller[arr[2]]);
} else {
router[item.method](item.url, permission(item.noAuth), controller[arr[2]]);
}
})
return app.use(router.routes())
} catch (e) {
return log.error(e)
}
}
实际例子
github: https://github.com/wenye123/learn-demo/tree/master/nodejs/api