数据权限

81 阅读2分钟

1,什么是数据权限?

举个例子,一个学校的校长能看到学生管理系统的全部学生的信息,进行管理维护 。而一个老师只能维护管理系统中自己班的学生,别的人根本看不到。

简而言之,就是同一张表,不同角色的人看到的是不一样的结果。

2. 场景

对同一个对象,不同的角色可以访问到的对象字段不一样。比如对于员工对象,领导可以看到员工的手机号,而普通人看不到员工的手机号。

针对这个场景,我们可以抽取出两种角色,一种是老板, 一种是员工。

老板可以看到所有人的手机号 , 而员工只能看到自己的手机号。

3. 伪代码实现

1. 基本思路

建立用户表 user

user_id user_name phone delete_mask

1 张三 1321321312 0

2 李四 2133192321 0

假设张三是老板

现在要实现的效果是 , 张三和李四访问同一个接口 , 张三能看到所有人 , 而李四只能看到自己。

首先 查看所有人的信息的sql

select * from user where user_id where delete_mask = 0;

自己只能看自己信息的sql

select * from user where user_id where delete_mask = 0 and user_id = X;

我们把 and user_id = X; 替换为 #{dynamicSql}

最后sql变为了

select * from user where user_id where delete_mask = 0 #{dynamicSql}

如果是老板访问 , 他就不需要拼接 and user_id = X;

如果是员工访问 , 他拼接的sql 都是 AND user_id = ; 其中 X是自己的user_id

2. 后端接口

//我们要求需要这种数据权限的接口都继承一个类
class BaseEntity{
    private String dynamicSql;
}

class User extends BaseEntity{
    private String userId;
    private String userName;
    private String phone;
}

@GetMapping("/infoList")
public List<User> getList(User user){
    return userMapper.select();
}

3. AOP技术

@DataScope
@GetMapping("/infoList")
public List<User> getList (User user) {
 return userMapper.select();
}

//这样上述接口就会被拦截了

4. 切面逻辑

@Before(DataScope.class)
public void doBefore(JoinPoint point ,  DataScope dataScope)
{
    //首先获得 user对象 把它强转为 BaseEntity
    Object params = joinPoint.getArgs()[0];


    BaseEntity baseEntity = null;
    if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
    {
        BaseEntity baseEntity = (BaseEntity) params;
    }

    //获得用户的id(一般都是从threadLocal里面获取)
    String userId = getUserId();

    //然后去处理 dynamicSql
    String dynamicSql = "";

    if ("1".equals(userId)) {
        //说明是老板 那么他的sql不需要任何拼接
        baseEntity.dynamicSql = null;
    }

    else{
        //说明不是老板  那么他的sql需要拼接 
        dynamicSql = "AND user_id = " + userId;
        baseEntity.dynamicSql = dynamicSql;
    }
}

5. 动态SQL

<select id="selectPictureList" parameterType="Picture" resultMap="PictureResult">
    select * from user where delete_mask = 0      
    <where>
        #{dynamicSql}
    </where>
</select>

4. 总结

这里只是做了一个简单的Demo , 但是基本讲清楚了数据权限的原理 , 无非就是通过AOP技术 , 然后去动态地对sql进行拼接。