20211229日记 开发springboot + vue + mybatis 棉花糖English 项目Day08

20211229日记 开发springboot + vue + mybatis 棉花糖English 项目Day08,第1张

2021/12/29日记 开发springboot + vue + mybatis 棉花糖English 项目Day08

昨天去学了shiro的授权,没有添加太多功能

先配置shiro注解
@RequiresAuthentication
验证用户是否登录,等同于方法subject.isAuthenticated()
@RequiresUser
验证用户是否被记忆,user有两种含义:
一种是成功登录的(subject.isAuthenticated() 结果为true);
另外一种是被记忆的(subject.isRemembered()结果为true)。
@RequiresGuest
验证是否是一个guest的请求,与@RequiresUser完全相反。
 换言之,RequiresUser  == !RequiresGuest。
此时subject.getPrincipal() 结果为null.
@RequiresRoles
例如:@RequiresRoles("aRoleName");
  void someMethod();
如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。
@RequiresPermissions
例如: @RequiresPermissions({"file:read", "write:aFile.txt"} )
  void someMethod();
开启shiro注解

配置在Shiroconfig中

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
在方法上添加注解
	@RequiresPermissions("adminUser:update")
    @RequestMapping("/updateAdminUser")
    public ResultObj updateAdminUser(@RequestBody AdminUser user){
        return adminUserService.updateAdminUser(user);
    }

像这样子添加

在realm中添加授权信息
 //用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("开始用户授权");
        String accessToken = (String) principalCollection.getPrimaryPrincipal();
        Integer id = Integer.valueOf(JwtUtils.getUserId(accessToken));

        //创建返回的info
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //先去redis里找,找不到再去claims里找


        //以上留空为redis做准备


        Claims claims = JwtUtils.getClaimsFromToken(accessToken);
        List permissions = (List) claims.get(Constant.JWT_PERMISSIONS_KEY);
        if(permissions != null){
            info.addStringPermissions(permissions);
        }
        return info;
    }

在用户第一次登录获得token的时候吧权限封装进token里

 @Override
    public ResultObj login(String username, String password) {

        AdminUser user = adminUserDao.login(username);
        int user_id = user.getId();
        String user_password = user.getPassword();
        //检查密码是否正确
        boolean passwordFlag = PasswordUtils.matches(user.getSalt(), password, user_password);
        if (user_id == 0 || !passwordFlag) {
            return new ResultObj(Constant.ERROR, Constant.USERNAME_PASSWORD_ERROR, null);
        }
        if (!user.getAvailable()) {
            return new ResultObj(Constant.ERROR, Constant.ADMINUSER_NOT_AVAILABLE, null);
        }
        //到这里就算登录通过,生成accessToken
        Map claims = new HashMap<>();

        //这里要加权限信息 加载claim中
        //留空
        //获取该用户所有角色
        List roles = adminRoleDao.getAllRolesByUserId(user_id);
        //用Set来去重用户所有权限
        Set permissions = new HashSet<>();

        for(AdminRole role : roles){
            //查询用户所拥有的每个角色所拥有的权限
            List permissionList = adminPermissionDao.getAllPermissionsByRoleId(role.getId());
            for (AdminPermission permission : permissionList){
                permissions.add(permission.getPercode());
            }
        }
        //将set转成string
        List permissionsToClaims = new ArrayList(permissions);

        claims.put(Constant.JWT_PERMISSIONS_KEY, permissionsToClaims);
        claims.put(Constant.JWT_USER_NAME, user.getUsername());

        //accessToken 中传入adminuser的id和claims
        String accessToken = JwtUtils.getAccessToken(String.valueOf(user_id), claims);

        //创建 refreshToken 存入redis
        //具体逻辑尚未实现
        String refreshToken = JwtUtils.getRefreshToken(String.valueOf(user_id),claims);

        //输出登录ip(为功能升级做准备)
        String ip = WebUtils.getRequest().getRemoteAddr();
        log.info("登录人" + username + "的IP为" + ip);
        return new ResultObj(Constant.OK, Constant.LOGIN_SUCCESS, accessToken);
    }
一个注意点
//不能注册成Bean不然springboot会先接手这个bean,然后原先的公共资源就不能访问了
    //@Bean
    //public JwtFilter jwtFilter() {
    //    return new JwtFilter();
    //}

在配置自己的过滤器的时候不能采用注入的方式,因为如果你用了Bean注入,这个过滤器就交给shiro管理了,这样的话你的配置就会乱了,所有在shiroconfig中采用new的方式注入filter

修改了数据库结构

将系统用户与角色的关系从多对一变成了多对多

原先在AdminUser表中写死了每个系统用户的角色
现在改成了一个系统用户可以拥有多个角色
从AdminUser中删除了role_id字段
添加了remark备注字段

抽离出来了一张admin_user_role字段

修改了查询用户的语句

    
        SELECT  u.id as id,u.username as username,u.nickname as nickname,
                u.available as available,u.remark as remark
        FROM `admin_user` as u
        left join admin_user_role as ur
        on u.id = ur.u_id
        
            
                
                and u.username like #{myUsername}
            
            
                
                and u.nickname like #{myNickname}
            
            
                and ur.r_id = #{role_id}
            
        

    
给table组件加了一个很牛逼的功能

首先是因为我返回的available属性是bool,再表格里直接这样写就显示不出来,经过查阅文档发现这样子需要对数据进行formatter
但是我又不想对子组件写死太多的规则,我更希望我对这个表格二次封装的组件有更高的自由度,经过查阅相关资料后我成功的实现了
只要在父组件实现formatter,传给子组件交给子组件去调用就好了
代码如下
父组件格式化代码,要加一个回调让子组件还可以收到value

//表格数据格式化
        formatUserForm(row, column, value, callback) {
            // console.log("start format");
            // console.log(column)
            let returnval;
            if (column.property === "available") {
                if (value === true) {
                    returnval = "可用";
                } else {
                    returnval = "不可用";
                }
            } else {
                returnval = value;
            }
            // let res = '';
            callback(returnval);
        },

子组件中检测有没有这个属性,如果有就采用父组件的格式化方法,没有就全部按照string 输出

还有好多东西要写,但是晚上学校断网,手机链热点老是抽风,明天再写

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5687760.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存