【权限管理平台】Day—03登录功能实现以及权限分配

【权限管理平台】项目开发Day—03

🏡  博客首页:派 大 星

⛳️  欢迎关注  ❤️ 点赞  🎒 收藏  ✏️ 留言

🎢  本文由派大星原创编撰

🚧  系列专栏:项目从0搭建

🎈  本系列项目从设计到实现源码全部开源免费学习使用,一起追向理想,欢迎各位大佬监督打卡开发!


在这里插入图片描述


🍉 难度分析

​       说起登录功能的实现可以实现的相当简单,简单到只需要让用户输入用户名密码就可以完成登录操作,但是网站的安全性无法得到保证 ❌;当然也可以实现的相当麻烦,加上各种外部校验,例如:验证码选字加减乘除,这样既可以美化我们的登录功能,同时又可以提高网站的安全性  ✅

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbt7owMx-1651561860125)(/Users/wumao/Documents/Typora笔记/typora-user-images/image-20220503132015322.png)]

🍒 技术介绍

​       本项目的登录功能我采用的是后面比较复杂的实现方式,由于用户在登录后,需要将该用户所携带的权限以及角色信息与用户紧贴,所以,这部分我采用的是将用户信息以及权限信息放入jwt中的荷载(Payload 中,通过Shiro自带的Realm中的授权机制进行用户与权限间的紧贴实现。同时也给登录功能添加了输入项——验证码,数据库对密码进行MD5二次加密入库处理,对平台的安全性进一步的提高。

🍑 集成验证码

引入依赖

<!--验证码-->
<dependency>
  <groupId>com.github.axet</groupId>
  <artifactId>kaptcha</artifactId>
  <version>0.0.9</version>
</dependency>

​       在集成验证码功能时需要配置关于它的属性,例如:生成的验证码是否有边框、边框的颜色、字体的颜色、大小等等属性!该配置类必须需要,不然启动项目会报错 ❌

验证码配置

@Configuration
public class CaptchaConfig {

    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
        //验证码生成器
        DefaultKaptcha defaultKaptcha=new DefaultKaptcha();
        //配置
        Properties properties = new Properties();
        //是否有边框
        properties.setProperty("kaptcha.border", "yes");
        //设置边框颜色
        properties.setProperty("kaptcha.border.color", "105,179,90");
        //边框粗细度,默认为1
        // properties.setProperty("kaptcha.border.thickness","1");
        //验证码
        properties.setProperty("kaptcha.session.key","code");
        //验证码文本字符颜色 默认为黑色
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        //设置字体样式
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        //字体大小,默认40
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        //验证码文本字符内容范围 默认为abced2345678gfynmnpwx
        // properties.setProperty("kaptcha.textproducer.char.string", "");
        //字符长度,默认为5
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        //字符间距 默认为2
        properties.setProperty("kaptcha.textproducer.char.space", "4");
        //验证码图片宽度 默认为200
        properties.setProperty("kaptcha.image.width", "100");
        //验证码图片高度 默认为40
        properties.setProperty("kaptcha.image.height", "40");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

​       但是生成的验证码我们又该如何去获取呢?两种方案:第一种存入Session中,在业务逻辑中采用request.getSession.setAttribute()/request.getSession.getAttribute()先存后取,当我们取出来之后可以调用 removeAttribute()对存入的验证码进行删除操作;第二种是将生成的验证码存储到Redis中的,在业逻辑中使用set()/get()方法对存入的验证码进行存取,但是使用Redis的好处是在存储的同时可以对指定的key设置过期时间,这样就可以不用再调用API进行删除操作。

生成验证码

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @Autowired
    private RedisService redisService;

    @ApiOperation(value = "验证码")
    @GetMapping(value = "/captcha",produces = "image/jepg")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws Exception{
        // 定义response输出类型为image/jpeg类型
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, mustrevalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        //-------------------生成验证码 begin --------------------------
        String text = defaultKaptcha.createText();
        System.out.println("验证码内容:"+text);
        //将验证码内容放入session
        //request.getSession().setAttribute("captcha",text);
      	//将验证码放入Redis中,并设置过期时间为1分钟
        redisService.set("captcha",text,60, TimeUnit.SECONDS);

        //根据文本验证码内容创建图形验证码
        BufferedImage image = defaultKaptcha.createImage(text);
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            //输出流输出图片
            ImageIO.write(image,"jpg",outputStream);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (outputStream != null){
                outputStream.close();
            }
        }
        //-------------------生成验证码 end --------------------------
    }

使用Swagger进行接口测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rXP1ILPU-1651561860126)(/Users/wumao/Documents/Typora笔记/typora-user-images/image-20220503143606416.png)]

测试成功❗️ 使用验证码可以降低被脚本暴力破解的风险!在图中在加入些许干扰竖线,使其破解脚本不能直接读取验证码中的内容。

🍇 登录功能集成

前提:

​       在实现登录功能时,我们需要用户在前端传递的用户名、密码以及验证码信息来进行校验【数据校验需要前后端共同参与才会使网站的安全性更高】但是这些信息部分是用户表中的信息,部分又不属于,遇到这种情况,通常需要我们对需要校验的数据进行二次封装,从而达到对代码的复用以及解耦。

数据封装

@Data
public class LoginVo {

    @ApiModelProperty(value = "用户账号")
    @NotBlank(message = "用户名不能为空")
    private String username;

    @ApiModelProperty(value = "用户密码")
    @NotBlank(message = "密码不能为空")
    private String password;

    @ApiModelProperty(value = "验证码")
    @NotBlank(message = "验证码不能为空")
    private String captcha;
}

​       代码中的@NotBlank(message="xxx")是一种注解式校验。比如我们判断字符串是否为空会选择在业务逻辑中使用StringUtils.isEmpty()等方法来进行判断,如果为空则抛出异常,但是如果我们需要校验的字段非常多,那么使用这种方式是完全不可取的,代码的冗余度过高。但是注解式校验的就解决了这方面的问题,使得我们的业务逻辑更简洁、易懂。❗️❗️❗️注意: 如果属性使用注解式校验的话,接口处传出对应参数对象时需要添加注解@Valid

登录功能的具体实现逻辑

    /**
     * 用户登录
     * @param vo
     * @return
     */
    @Override
    public RespBody login(LoginVo vo) {
        String code = (String) redisService.get("captcha");
        //判断验证码是否过期
        if (!redisService.hasKey("captcha")){
            throw new BusinessException(BaseResponseCode.KEY_ALREADY_EXPIRED);
        }

        //忽略字符大小写校验验证码是否正确
        if (!vo.getCaptcha().equalsIgnoreCase(code)){
            throw new BusinessException(BaseResponseCode.CAPTCHA_ERROR);
        }

        //判断用户是否存在
        SysUser user = userMapper.getUserByName(vo.getUsername());
        if (user == null){
            throw new BusinessException(BaseResponseCode.ACCOUNT_ERROR);
        }
        //判断用户状态
        if (user.getStatus() == 2){
            throw new BusinessException(BaseResponseCode.ACCOUNT_LOCKED);
        }
        //校验密码
        if (!PasswordUtils.matches(user.getSalt(),vo.getPassword(),user.getPassword())){
            throw new BusinessException(BaseResponseCode.ACCOUNT_PASSWORD_ERROR);
        }
        RespBody body = new RespBody();
        body.setId(user.getId());
        body.setUsername(user.getUsername());
        Map<String,Object> claims = new HashMap<>();
      	//将用户角色/权限信息添加到荷载中
        claims.put(Constant.ROLES_INFOS_KEY,getRoleByUserId(user.getId()));
        claims.put(Constant.PERMISSIONS_INFOS_KEY,getPermissionByUserId(user.getId()));
        claims.put(Constant.JWT_USER_NAME,user.getUsername());
        String accessToken = JwtTokenUtil.getAccessToken(user.getId(), claims);
        body.setAccessToken(accessToken);
        return body;
    }

测试接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZqrT7tPd-1651561860126)(/Users/wumao/Documents/Typora笔记/typora-user-images/image-20220503150726923.png)]

测试成功❗️❗️

今天的内容到这里就结束了,希望可以帮助到各位路过的小伙伴!

新鲜出炉的代码将会及时更新到Gitee仓库

以上代码属于部分实现,想要了解全部配置请移步 派大星的Gitee仓库

今天的工作就进行到这里!希望大佬们可以监督派大星一步步从0搭建该平台!
在这里插入图片描述

  • 36
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论
【实例简介】 项目采用经典DDD架构(用沃恩.弗农大神的话,其实这是DDD-Lite)思想进行开发,简洁而不简单,实用至上,并且所写每一行代码都经过深思熟虑,符合SOLID规则! ####当前版本 3.0 alpha版(2017-2-7) 采用全新工作流,实现自定义表单处理; 2.0版(2016-10-31) 支持多流程模板; 增加Ace admin界面支持 秀外 输入图片说明 输入图片说明 输入图片说明 慧中 教科书级的分层思想,哪怕苛刻的你阅读的是大神级精典大作(如:《企业应用架构模式》《重构与模式》《ASP.NET设计模式》等),你也可以参考本项目。不信?有图为证,Resharper自动生成的项目引用关系,毫无PS痕迹! 输入图片说明 实用 符合国情的RBAC(基于角色的访问控制),可以直接应用到你的系统。 权限资源 菜单权限 经理和业务员登陆系统拥有的功能菜单是不一样的 按钮权限 经理能够审批,而业务员不可以 数据权限 A业务员看不到B业务员的单据 字段权限 某些人查询客户信息时看不到客户的手机号或其它字段 用户应用系统的具体操作者,我这里设计用户是可以直接给用户分配菜单/按钮,也可以通过角色分配权限。 角色为了对许多拥有相似权限的用户进行分类管理,定义了角色的概念,以上所有的权限资源都可以分配给角色,角色和用户N:N的关系。 机构树形的公司部门结构,国内公司用的比较多,它实际上就是一个用户组,机构和用户设计成N:N的关系,也就是说有时候一个用户可以从属于两个部门,这种情况在我们客户需求中的确都出现过。 ####系统工程结构: OpenAuth.Domain 系统领域层 OpenAuth.Repository 系统仓储层,用于数据库操作 OpenAuth.App 应用层,为界面提供接口 OpenAuth.Mvc 采用基于jquery与bootstrap的B-JUI界面 OpenAuth.UnitTest 单元测试 Infrastructure 通用工具集合 ####使用 管理员可直接在登录界面点击基于精典DDD的权限管理 - 点击以开发者账号登录登录; 普通应用账号使用:test(密码:test)登录; ####后续 更多狂野的功能,正在玩命加载中,敬请期待... 更多文档正在整理中.... 当然,如果你想学习完整的DDD框架,可以参考我的另一个项目(BestQ&A--开源中国推荐项目/集CQRS AES等DDD高级特性于一体的问答系统) 【实例截图】
课程简介:历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring BootSpring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT派同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值