用Springboot框架实现登录页面验证码

学习了Java两个月后,自己开始跟着老师做了一个小项目,我想记录一下自己第一次做项目的过程,以及自己遇到的一些难题。
老师已经把整个项目给我们讲解完了,但是你懂的,不经过自己的实际操作,你是很难从项目中学到东西的。于是我开始从前端页面开始写,按照自己的理解和参照老师的代码,我成功把注册和登录页面写出来了(哈哈,我的基础的的确很差),而且实现了第一个难题的突破,也就是验证码这个部分,如下图:
在这里插入图片描述(先忽略我这个后端仔写的页面~~~)
看,这个验证码还不错吧,只要点击它,就可以实时刷新啦。因为前端用的是Vue.js、ElementUI、还有Axios写的,所以把验证码传到页面还算简单,真正的难点是画验证码的部分。你没听错,这个验证码是画出来的,代码真的很神奇。我把验证码的实现封装在了一个工具类中,话不多说,直接上代码:
话不多说,直接上代码,

/**
 * 验证码工具类
 */
public final class VerifyCodeUtil {
    /*定义图片的width*/
    private static int WIDTH = 80;
    /*定义图片的height*/
    private static int HEIGHT = 30;
    /*定义图片上显示的验证码个数*/
    private static int CODECOUNT = 4;
    /*字符间隔*/
    private static final int CHARACETRSPACING = 8;
    /*字体大小*/
    private static final int FONTHEIGHT = 24;
    /*干扰线*/
    private static final int LINENUMBER = 25;
    /*字符垂直位置*/
    private static final int VERTICALPOSITION = 24;
    private static final char[] CODESEQUENCE = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
            'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
            'o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0'};
    /*无参构造器*/
    private VerifyCodeUtil(){}

    /**
     * 生成验证码字符串
     * @param count 验证码字符个数
     * @return 返回验证码字符串
     */
    public static String generateVerifyCode(int count){
        //产生随机数
        Random random = new Random();
        //生成验证码
        StringBuilder randomCode = new StringBuilder();/*StringBuilder可变字符串序列*/
        for (int i = 0; i < count; i++) {
            //获取一位验证码
            String code = String.valueOf(CODESEQUENCE[random.nextInt(CODESEQUENCE.length)]);
            randomCode.append(code);/*字符串拼接*/
        }
        return randomCode.toString();
    }

    /**
     * 生成验证码字符串
     * @return 返回验证码字符串
     */
    public static String generateVerifyCode(){//方法的重载
        return generateVerifyCode(CODECOUNT);//静态方法中只能调用静态方法
    }

    /**
     * 生成验证码图片
     * @param width 验证码图片的宽度,默认95
     * @param  height 验证码图片的高度,默认30
     * @param code 验证码字符串
     * @return 返回创建好的画布对象
     */
    public static BufferedImage outputImage(Integer width, Integer height, String code){
        if(!ObjectUtil.isEmpty(width)){//Spring工具包中的方法
            WIDTH = width;//为图片设置宽度
        }
        if(!ObjectUtil.isEmpty(height)){
            HEIGHT = height;//为图片设置高度
        }
        if(ObjectUtil.isEmpty(code)){
            return null;//做这些判断都是为了防止出现空指针异常
        }
        //创建画布对象(不带透明色)
        BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //创建画笔对象
        Graphics gd = buffImg.getGraphics();
        //创建生成随机数对象
        Random random = new Random();
        //设置画布背景色(白色)
        gd.setColor(Color.WHITE);
        //根据设置的背景色填充画布
        gd.fillRect(0, 0, WIDTH, HEIGHT);
        //创建字体对象
        Font font = new Font("Arial", Font.BOLD, FONTHEIGHT);
        //给画笔对象设置字体
        gd.setFont(font);
        //给画笔对象设置颜色
        gd.setColor(Color.BLACK);
        //给画布绘制边框
        gd.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
        //生成验证码
        char[] codes = code.toCharArray();
        for (int i = 0; i < codes.length; i++) {
            //设置颜色
            gd.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            //绘制验证码
            gd.drawString(String.valueOf(codes[i]), CHARACETRSPACING + i * 2 * CHARACETRSPACING, VERTICALPOSITION);
        }
        //设置干扰线颜色(深灰色)
        gd.setColor(Color.DARK_GRAY);
        //干扰线
        for (int i = 0; i < LINENUMBER; i++) {
            //线的起始X坐标
            int startX = random.nextInt(WIDTH);
            //线的起始Y坐标
            int startY = random.nextInt(HEIGHT);
            //线的结束X坐标
            int endX = random.nextInt(VERTICALPOSITION);
            //线的结束Y坐标
            int endY = random.nextInt(VERTICALPOSITION);
            //绘制直线
            gd.drawLine(startX, startY, startX + endX, startY + endY);
        }
        return buffImg;
    }
    /**
     * 输出验证码图片流
     * @param w 宽度
     * @param h 高度
     * @param code 验证码字符串
     * @param os 输出流
     */
    public static void outputImage(Integer w, Integer h, String code, OutputStream os) throws IOException {
        if(ObjectUtil.isEmpty(code)){
            return;
        }
        // 创建画布对象
        BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 创建画笔对象
        Graphics gd = bi.getGraphics();
        // 创建生成随机数对象
        Random random = new Random();
        // 设置画布背景色
        gd.setColor(Color.DARK_GRAY);
        // 根据设置的背景色填充画布
        gd.fillRect(0, 0, WIDTH, HEIGHT);
        // 创建字体对象
        Font font = new Font("Arial", Font.BOLD, FONTHEIGHT);
        // 给画笔对象设置字体
        gd.setFont(font);
        // 给画笔设置颜色
        gd.setColor(Color.BLACK);
        // 给画布绘制边框
        //gd.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
        // 设置干扰线颜色
        gd.setColor(Color.BLACK);
        // 干扰线
        for (int i = 0; i < LINENUMBER; i++) {
            // 线的起始X坐标
            int startX = random.nextInt(WIDTH);
            // 线的起始Y坐标
            int startY = random.nextInt(HEIGHT);
            // 线的结束X坐标
            int endX = random.nextInt(VERTICALPOSITION);
            // 线的结束Y坐标
            int endY = random.nextInt(VERTICALPOSITION);
            // 绘制直线
            gd.drawLine(startX, startY, startX + endX, startY + endY);
        }
        // 生成验证码
        char[] codes = code.toCharArray();
        for (int i = 0; i < codes.length; i++) {
            // 设置颜色
            gd.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            // 绘制验证码
            gd.drawString(String.valueOf(codes[i]), CHARACETRSPACING + i * 2 * CHARACETRSPACING, VERTICALPOSITION);
        }
        gd.dispose();
        ImageIO.write(bi, "png", os);
    }
    /**
     * 输出验证码图片流
     * @param code 验证码
     * @param os 创建的输出流
     */
    public static void outputImage(String code, OutputStream os) throws IOException {
        outputImage(WIDTH, HEIGHT, code, os);
    }
}

这就是实现验证码的整个过程啦。我们做的是一个简单的客户管理系统,后续还会继续更新嗷~

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以通过Spring Security来实现登录注册和登出功能,同时使用第三方库生成图形验证码。 1. 登录注册 在Spring Boot中使用Spring Security实现登录注册功能,需要引入以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 然后创建一个SecurityConfig类来配置Spring Security,示例代码如下: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/registration").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 其中,configure(AuthenticationManagerBuilder auth)方法用于配置用户认证方式,这里使用了UserDetailsService来获取用户信息,同时使用BCryptPasswordEncoder进行密码加密;configure(HttpSecurity http)方法用于配置请求授权和登录等信息。 2. 图形验证码 可以使用第三方库Kaptcha来生成图形验证码,需要引入以下依赖: ```xml <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> ``` 然后创建一个KaptchaConfig类来配置Kaptcha,示例代码如下: ```java @Configuration public class KaptchaConfig { @Bean public Producer captcha() { Properties properties = new Properties(); properties.put("kaptcha.border", "no"); properties.put("kaptcha.textproducer.font.color", "black"); properties.put("kaptcha.image.width", "150"); properties.put("kaptcha.image.height", "50"); properties.put("kaptcha.textproducer.char.length", "4"); Config config = new Config(properties); DefaultKaptcha kaptcha = new DefaultKaptcha(); kaptcha.setConfig(config); return kaptcha; } } ``` 在Controller中使用Kaptcha生成图形验证码,示例代码如下: ```java @RestController public class CaptchaController { @Autowired private Producer captchaProducer; @GetMapping("/captcha") public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception { response.setDateHeader("Expires", 0); response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); response.addHeader("Cache-Control", "post-check=0, pre-check=0"); response.setHeader("Pragma", "no-cache"); response.setContentType("image/jpeg"); String capText = captchaProducer.createText(); request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, capText); BufferedImage bi = captchaProducer.createImage(capText); ServletOutputStream out = response.getOutputStream(); ImageIO.write(bi, "jpg", out); try { out.flush(); } finally { out.close(); } } } ``` 在前端页面中使用img标签来显示图形验证码,示例代码如下: ```html <img src="/captcha" alt="Captcha" /> ``` 3. 登出 在SecurityConfig中配置logout()方法即可实现登出功能,示例代码如下: ```java @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/registration").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } ``` 在前端页面中使用a标签访问/logout路径即可实现登出,示例代码如下: ```html <a href="/logout">Logout</a> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值