web开发用户撤销、角色撤销实时性检查

我们在开发系统时,会遇到常规功能如撤销用户登录权限,撤销某个角色的登录权限。情况一:用户这张表通常也会添加一个disabled字段,当我们将它设为false时,即表示该用户是禁用状态,不能登录的,但是通常我们系统校验用户是否能访问系统,是在访问登录接口时才去校验该字段,说明该用户即使被禁用后,还是能使用一段时间(长度为token过期时间);情况二:在用户、角色、系统(项目为多系统,角色系统表中增加一个字段保存能访问的系统菜单)控制权限开发中,当我们撤销某个角色对某个系统的访问权限后,只要用户不刷新页面(访问角色系统权限接口),就还有权限访问该系统。

针对上面两种情况,我们可以使用JWT中间件(不同语言有不同的JWT中间件以供使用)中的撤销token有效的方法中添加检验方法,比如针对node.js的JWT中间件的isRevoked方法中增加检验方法,因为每次方法接口时,都会经过该中间件。大致思想就是,情况一:当将用户禁用时,将该用户添加到redis中,过期时间就是token有效时间,在isRevoked方法中,将该用户拿到redis去比对,如果有该用户,则该用户为禁用状态,就撤销token有效性;情况二:在角色创建,更新接口最后都将该用户不能方法的系统添加到redis中,然后isRevoked方法中,利用该角色id和正在访问的系统名到redis中查询,如果有则撤销token有效性

实例代码:

JWT中间件指定的撤销token有效性的isRevoked()方法:

async isRevoked(req: any, payload, done) {
    let revoked = await req.service.token.isRevoked(payload);
    if (revoked) {
      return done(new IError(1012, "jwt expired."));
    }

    done(null);
  }

token中的isRevoked()方法,就是在调用微服务中的方法:

async isRevoked({ id, version, role_ids = [], system }) {
    let result = false;
    if (id && Number.isInteger(version)) {
      result = await this.broker.call("token.isRevoked", { id, version, role: "employee", role_ids, system });
    }

    return result;
  }

微服务中的isRevoked()方法:

async isRevoked(ctx){
        let { role_ids = [], system } = ctx.params;

        // 检查角色吊销
        for(let role of role_ids){
            let key = this.constructor._getRoleKey(role);
            let exist = await redis.hexists(key,system);
            if(exist){
                return exist;
            }
        }

        // 检查用户吊销
        return redis.exists(this.constructor._getUserKey(ctx.params));
    }

因为我是将redis方法放在微服务中的,所有方法封装了几层,如果你没有使用微服务,直接在token模块中添加校验方法

你可能感兴趣的:(web开发用户撤销、角色撤销实时性检查)