• 图形验证码(基础)


    一、生成图形验证码

      1、根据随机数生成图片

      2、将随机数存储到session中

      3、将生成的图片写到接口的响应中

      基类:

    package com.nxz.security.core.validatecode;
    
    import lombok.Data;
    
    import java.awt.image.BufferedImage;
    import java.time.LocalDateTime;
    
    @Data
    public class ImageCode {
    
        private BufferedImage image;
    
        private String code;//随机数
    
        private LocalDateTime expireTime;
    
        public ImageCode(BufferedImage image, String code, int expireIn) {
            this.image = image;
            this.code = code;
            this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
        }
    
        public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
            this.image = image;
            this.code = code;
            this.expireTime = expireTime;
        }
    }

      控制层:

      

    package com.nxz.security.core.controller;
    
    import com.nxz.security.core.validatecode.ImageCode;
    import org.springframework.social.connect.web.HttpSessionSessionStrategy;
    import org.springframework.social.connect.web.SessionStrategy;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.context.request.ServletWebRequest;
    
    import javax.imageio.ImageIO;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    @RestController
    public class ValidateCodeController {
    
        private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
    
        private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
    
        @GetMapping("/code/image")
        public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //生成图片
            ImageCode imageCode = createImageCode(request);
    
            //将随机数存到session中
            sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
            ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
        }
    
        private ImageCode createImageCode(HttpServletRequest request) {
            // 在内存中创建图象
            int width = 85, height = 20;
            BufferedImage image = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            // 获取图形上下文
            Graphics g = image.getGraphics();
            // 生成随机类
            Random random = new Random();
            // 设定背景色
            g.setColor(getRandColor(200, 250));
            g.fillRect(0, 0, width, height);
            // 设定字体
            g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
            // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
            g.setColor(getRandColor(160, 200));
            for (int i = 0; i < 155; i++) {
                int x = random.nextInt(width);
                int y = random.nextInt(height);
                int xl = random.nextInt(12);
                int yl = random.nextInt(12);
                g.drawLine(x, y, x + xl, y + yl);
            }
            // 取随机产生的认证码(6位数字)
            String sRand = "";
            for (int i = 0; i < 6; i++) {
                String rand = String.valueOf(random.nextInt(10));
                sRand += rand;
                // 将认证码显示到图象中
                g.setColor(new Color(20 + random.nextInt(110), 20 + random
                        .nextInt(110), 20 + random.nextInt(110)));
                // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
                g.drawString(rand, 13 * i + 6, 16);
            }
    
            // 图象生效
            g.dispose();
    
            return new ImageCode(image, sRand, 60);
        }
    
        /*
         * 给定范围获得随机颜色
         */
        private Color getRandColor(int fc, int bc) {
            Random random = new Random();
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int r = fc + random.nextInt(bc - fc);
            int g = fc + random.nextInt(bc - fc);
            int b = fc + random.nextInt(bc - fc);
            return new Color(r, g, b);
        }
    }

      页面:

      

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定义登录页面</title>
    </head>
    <body>
    
    <h2>自定义登录页面</h2>
    
    <form action="/authentication/form" method="POST">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"></td>
            </tr>
    
            <tr>
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td>图形验证码:</td>
                <td>
                    <input type="text" name="imagecode">
                    <img src="/code/image" alt="">
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <button type="submit">登录</button>
                </td>
            </tr>
        </table>
    
    
    </form>
    
    </body>
    </html>

      效果:

      

    ps:图形验证码的各种参数都可以配置到application.yml中,并且图形验证码生成器可以配置为可配置类,默认实现一种,动态配置覆盖默认配置

  • 相关阅读:
    [GO]使用bufio的文件读取方式
    php开发工程师面必问题
    一位资深php程序员在北京的面试30个题目
    GIT 分支管理:创建与合并分支、解决合并冲突
    linux下挂在u盘,移动硬盘的方法,转移服务器资料的时候,使用移动硬盘什么最方便了
    php后台对接ios,安卓,API接口设计和实践完全攻略,涨薪必备技能
    navicat 官方使用手册,中文版,快捷键大全
    Memcached之缓存雪崩,缓存穿透,缓存预热,缓存算法
    Memcache 笔记(2)
    Memcache笔记(1)
  • 原文地址:https://www.cnblogs.com/nxzblogs/p/10808386.html
Copyright © 2020-2023  润新知