基于koa2的权限认证思路

 转载文章  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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值