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

本文详细介绍了在SpringBoot项目中如何使用Shiro进行用户权限管理,包括用户的增删改查功能、重置密码、登录认证逻辑以及前端交互。着重讲解了Shiro的登录认证流程,并实现了自定义Matcher以验证JWT token的合法性,确保只有合法用户才能访问受保护的接口。
摘要由CSDN通过智能技术生成

后端部分

完成了系统用户的增删改查功能

controller

//通过查询条件获取所有用户
    @RequestMapping("/getAllAdminUser")
    public ResultObj getAllAdminUser(@RequestParam(required=false,defaultValue="",name = "username") String username,
                                           @RequestParam(required=false,defaultValue="",name ="nickname") String nickname,
                                           @RequestParam(required=false,defaultValue="",name ="role_id")String role_id,
                                           @RequestParam(required=false,defaultValue="5",name ="limit")String pageSize,
                                           @RequestParam(required=false,defaultValue="1",name ="page")String pageNum){
        Integer roleId;
        if(StringUtils.hasLength(role_id)){
            roleId = Integer.parseInt(role_id);
        }
        else{
            roleId = null;
        }
        return adminUserService.getAllAdminUser(username, nickname, roleId,Integer.parseInt(pageSize), Integer.parseInt(pageNum));
    }

    //改
    @RequestMapping("/updateAdminUser")
    public ResultObj updateAdminUser(@RequestBody AdminUser user){
        return adminUserService.updateAdminUser(user);
    }

    //删
    @RequestMapping("/deleteAdminUserByIds")
    public ResultObj deleteAdminUserByIds(@RequestBody ArrayList<Integer> ids){
        return adminUserService.deleteAdminUserByIds(ids);
    }

    //增
    @RequestMapping("/addAdminUser")
    public ResultObj addAdminUser(@RequestBody AdminUser user){
        return adminUserService.addAdminUser(user);
    }

serviceimpl

@Override
    public ResultObj getAllAdminUser(String username, String nickname, Integer role_id, Integer pageSize, Integer pageNum) {
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<AdminUser> adminUsers = adminUserDao.getAllAdminUser(username, nickname, role_id);
            PageInfo<AdminUser> pageInfo = new PageInfo<>(adminUsers);
            return new ResultObj(Constant.OK, Constant.QUERY_SUCCESS, pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultObj(Constant.ERROR, Constant.QUERY_ERROR, null);
        }
    }

    @Override
    public ResultObj updateAdminUser(AdminUser user) {
        try {
            boolean flag = adminUserDao.updateAdminUser(user);
            if (flag) {
                return new ResultObj(Constant.OK, Constant.UPDATE_SUCCESS, null);
            } else {
                return new ResultObj(Constant.ERROR, Constant.UPDATE_ERROR, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultObj(Constant.ERROR, Constant.UPDATE_ERROR, null);
        }
    }

    @Override
    @Transactional
    public ResultObj deleteAdminUserByIds(List<Integer> ids) {
        try {
            boolean flag = adminUserDao.deleteAdminUserByIds(ids);
            if (flag) {
                return new ResultObj(Constant.OK, Constant.DELETE_SUCCESS, null);
            } else {
                return new ResultObj(Constant.ERROR, Constant.DELETE_ERROR, null);
            }
        } catch (Exception e) {
            return new ResultObj(Constant.ERROR, Constant.DELETE_ERROR, null);
        }
    }

    @Override
    public ResultObj addAdminUser(AdminUser user) {
        String salt = PasswordUtils.getSalt();
        String password = PasswordUtils.encode(user.getPassword(),salt);
        user.setSalt(salt);
        user.setPassword(password);
        try {
            boolean flag = adminUserDao.addAdminUser(user);
            if(flag){
                return new ResultObj(Constant.OK, Constant.ADD_SUCCESS,null);
            }
            else{
                return new ResultObj(Constant.ERROR, Constant.ADD_ERROR,null);
            }
        }catch (Exception e) {
            e.printStackTrace();
            return new ResultObj(Constant.ERROR, Constant.ADD_ERROR, null);
        }
    }

mapper

<!--查-->
    <select id="getAllAdminUser"  resultMap="baseResultMap">
        SELECT id,username,nickname,role_id,available
        FROM admin_user
        <where>
            <if test="username != null and ! &quot;&quot;.equals(username)">
                <bind name="myUsername" value="'%' + username + '%'"/>
                username like #{myUsername}
            </if>
            <if test="nickname != null and ! &quot;&quot;.equals(nickname)">
                <bind name="myNickname" value="'%' + nickname + '%'"/>
                nickname like #{myNickname}
            </if>
            <if test="role_id != null">
                role_id = #{role_id}
            </if>
        </where>
    </select>
    <!--改-->
    <update id="updateAdminUser" parameterType="AdminUser">
        UPDATE admin_user
        <set>
            <if test="adminUser.username != null and ! &quot;&quot;.equals(adminUser.username)">
                username = #{adminUser.username},
            </if>
            <if test="adminUser.nickname != null and ! &quot;&quot;.equals(adminUser.nickname)">
                nickname = #{adminUser.nickname},
            </if>
            <if test="adminUser.roleId != null">
                role_id = #{adminUser.roleId},
            </if>
        </set>
        WHERE
        id = #{adminUser.id};
    </update>

    <!--删-->
    <delete id="deleteAdminUserByIds">
        DELETE FROM admin_user
        WHERE id in
        <foreach collection="ids" item = "id" index = "no" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

    <!--增-->
    <insert id="addAdminUser" parameterType="AdminUser">
        INSERT INTO admin_user (username,nickname,password,role_id,createtime,salt)
        VALUES (#{user.username},#{user.nickname},#{user.password},#{user.roleId},NOW(),#{user.salt})
    </insert>

完成了重置密码功能

/重置密码
    @RequestMapping("/restPassword")
    public ResultObj restPassword(Integer id){
        log.info(String.valueOf(id));
        return adminUserService.restPassword(id);
    }
//重置密码
    @Override
    public ResultObj restPassword(Integer id) {
        String salt = PasswordUtils.getSalt();
        String password = PasswordUtils.encode("123456", salt);
        try {
            boolean flag = adminUserDao.restPassword(id, password, salt);
            if (flag) {
                return new ResultObj(Constant.OK, Constant.RESET_SUCCESS, null);
            } else {
                return new ResultObj(Constant.ERROR, Constant.RESET_ERROR, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultObj(Constant.ERROR, Constant.RESET_ERROR, null);
        }
    }

前端

完成子组件对父组件的事件的调用

在父组件中对子组件添加想要触发的事件
在这里插入图片描述
在子组件中添加触发函数

在这里插入图片描述

// 触发父父组件事件按钮
        //data 数据,
        //fun 父组件函数名
        btnClick(fun,data) {
            console.log(fun);
            // this.$emit("click_" + (idx + 1), e);
            this.$emit(fun,data);
        },

这样就可以实现子组件调用父组件了

在这里插入图片描述

完成了前端对数据的更新,重置密码,删除功能

methods: {
        //重置搜索栏
        reset() {
            let _this = this;
            _this.queryAdminUserForm.username = "";
            _this.queryAdminUserForm.nickname = "";
            _this.queryAdminUserForm.roleId = "";
            _this.$refs.table.getTableData();
        },
        // 发送条件搜索请求
        search() {
            this.$refs.table.getTableData();
        },

        // 单条数据更新
        updateAdminUser(data) {
            let _this = this;
            if (data.id == 1) {
                _this.$message.error("你的权限不能编辑此用户");
                return;
            }
            _this.updateAdminUserFormVisible = true;
            _this.updateForm.id = data.id;
            _this.updateForm.nickname = data.nickname;
            _this.updateForm.roleId = data.roleId;
        },
        //发送编辑请求
        toUpdateAdminUser(data) {
            let _this = this;
            adminUserApi
                .updateAdminUser(data)
                .then((res) => {
                    let result = res.data;
                    if (result.code == 200) {
                        _this.$message(result.msg);
                        this.$refs.table.getTableData();
                    } else {
                        _this.$message.error(result.msg);
                    }
                })
                .catch((error) => {
                    _this.$message.error("服务器错误,请稍后再试");
                });
            _this.updateAdminUserFormVisible = false;
        },
        //重置密码
        resetPassword(data) {
            let _this = this;
            if (data.id == 1) {
                _this.$message.error("你的权限不能重置此用户");
                return;
            }
            _this
                .$confirm("是否要重置该用户的密码为123456", "警告", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                })
                .then(() => {
                    //todelete
                    console.log("去重置");
                    _this.toResetPassword(data.id);
                })
                .catch(() => {});
        },
        toResetPassword(id) {
            let data = {
                id
            }
            adminUserApi
                .restPassword(data)
                .then((res) => {
                    let result = res.data;
                    if (result.code == 200) {
                        this.$message(result.msg);
                        this.$refs.table.getTableData();
                    } else {
                        this.$message.error(result.msg);
                    }
                })
                .catch((error) => {
                    this.$message.error("服务器错误,请稍后再试");
                });
        },
        //删除用户
        deleteAdminUser(data) {
            let _this = this;
            if (data.id == 1) {
                _this.$message.error("你的权限不能删除此用户");
                return;
            }
            _this
                .$confirm("是否要永久删除此系统用户", "警告", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                })
                .then(() => {
                    //todelete
                    _this.toDelete(data.id);
                })
                .catch(() => {});
        },
        toDelete(id) {
            let ids = [id];
            adminUserApi
                .deleteAdminUserByIds(ids)
                .then((res) => {
                    let result = res.data;
                    if (result.code == 200) {
                        this.$message(result.msg);
                        this.$refs.table.getTableData();
                    } else {
                        this.$message.error(result.msg);
                    }
                })
                .catch((error) => {
                    this.$message.error("服务器错误,请稍后再试");
                });
        },
    },

效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

又去学shiro了

先去仔细了解了shiro登录认证的逻辑
https://blog.csdn.net/caoyang0105/article/details/82769293

重写了登录逻辑
现阶段的登录逻辑是
后端对所有的接口请求进行拦截,除了登录接口

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        log.info("JwtFilter-->>>isAccessAllowed-Method:init()");
        //是否是尝试登录,如果尝试登陆直接返回true
        if (isLoginAttempt(request, response)) {
            return true;
        }

        //如果不是访问登录api,正常的情况下HEADER中应该有token
        HttpServletRequest req = (HttpServletRequest) request;
        String token = req.getHeader(Constant.HEADER_TOKEN_KEY);
        if(StringUtils.hasLength(token)){
            //如果存在,则进入executeLogin方法执行登入,检查token 是否正确
            try {
                executeLogin(request, response);
                return true;
            } catch (Exception e) {
                throw new AuthenticationException(e.getMessage());
            }
        }
        else{
            //无token非法访问请求
            throw new AuthenticationException("非法访问");
        }
    }

如果不是登录接口,就去获取浏览器响应头中的token
如果没有token说明是没有登陆就访问,就是非法访问

如果header里面有token ,就拿着这个token 去LeeRealm里面去进行登录认证
在这里插入图片描述
LeeRealm
在这里插入图片描述
这里面写了一个LeeMatcher来进行校验,因为shiro会再LeesShiro返回后去找一个Matcher去验证密码,这时候因为现在存的数据里没有密码,所以覆写一个Matcher让他去校验token是否合法而不是去校验密码

在这里插入图片描述
并在shiroconfig中配置这个Matcher
在这里插入图片描述
现在太晚了,先把明天要写的东西想好,我怕我明天忘了

明天把controller中的登录逻辑放到Realm中去,完完全全由shiro控制登录,不过我感觉还是不现实,因为我并不需要shiro来帮我控制密码,我只需要他帮我控制token是否有效,是否过期我就可以控制用户的登陆状态了,所以先暂缓一下,具体怎么写明天再写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值