springboot 登录时 图片验证码验证

现在springboot项目添加索引

<!--用户登录界面验证码-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

书写配置类KaptchaConfig,和公共类KaptchaUtils
KaptchaConfig.class

@Component
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha getDefaultKaptcha() {
        com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "no");
        // 边框颜色
        properties.setProperty("kaptcha.border.color", "black");
        //边框厚度
        properties.setProperty("kaptcha.border.thickness", "1");
        // 图片宽
        properties.setProperty("kaptcha.image.width", "120");
        // 图片高
        properties.setProperty("kaptcha.image.height", "40");
        //图片实现类
        properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
        //文本实现类
        properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
        //文本集合,验证码值从此集合中获取
        properties.setProperty("kaptcha.textproducer.char.string", "01234567890");
        //验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        //字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体");
        //字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "black");
        //文字间隔
        properties.setProperty("kaptcha.textproducer.char.space", "5");
        //干扰实现类
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
        //干扰颜色
        properties.setProperty("kaptcha.noise.color", "blue");
        //干扰图片样式
        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
        //背景实现类
        properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
        //背景颜色渐变,结束颜色
        properties.setProperty("kaptcha.background.clear.to", "white");
        //文字渲染器
        properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

公共类KaptchaUtils.class

public class KaptchaUtils {
    /**
     * 生成验证码图片
     * @param request 设置session
     * @param response 转成图片
     * @param captchaProducer 生成图片方法类
     * @param validateSessionKey session名称
     * @throws Exception
     */
    public static void validateCode(HttpServletRequest request, HttpServletResponse response, DefaultKaptcha captchaProducer, String validateSessionKey) throws Exception{
        // Set to expire far in the past.
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // 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");

        // create the text for the image
        String capText = captchaProducer.createText();

        // store the text in the session
        request.getSession().setAttribute(validateSessionKey, capText);

        // create the image with the text
        BufferedImage bi = captchaProducer.createImage(capText);

        ServletOutputStream out = response.getOutputStream();

        // write the data out
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}


写完后我们来写前端的代码

 <div class="control-group">
       <div class="controls" style="text-align: center">
       <img src="/loginValidateCode" th:src="@{/user/loginValidateCode}" id="loginValidateCode" name="loginValidateCode"
             onclick="uploadLoginValidateCode()" class="m-margin-bottom" alt="">
     <input type="text" id="validateCode" name="validateCode" class="form-control" style="width: 200px">
         </div>
  </div>

先一个可以装验证码图片,并且给它id:loginValidateCode,以及点击的事件uploadLoginValidateCode()
th:src="@{/user/loginValidateCode}"是图片的路径 由于springboot要使用thymeleaf
故必须在html上头添加

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">

显示图片书写完毕后 写触发的事件

 function uploadLoginValidateCode() {
        /*路径一定要加上项目的跟路径*/
        $("#loginValidateCode").attr("src","/user/loginValidateCode?random="+new Date().getMilliseconds());
    }

接下来书写后端的代码

/**
     * 登录验证码SessionKey
     */
    public static final String LOGIN_VALIDATE_CODE = "login_validate_code";

    /**
     * 登录验证码图片
     */
    @GetMapping("/loginValidateCode")
    public void loginValidateCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        KaptchaUtils.validateCode(request,response,kaptchaProducer,LOGIN_VALIDATE_CODE);
    }

你会发现为啥这边只有@GetMapping("/loginValidateCode"),而图片的地址是@{/user/loginValidateCode}
这是由于我在编写Controller的时候有个习惯 喜欢在前面添加有关该类的@RequestMapping("/user")

这样我们就可以点击图片更换验证码了
接下来把前端的所有代码贴出来

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head >
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册登录</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
    <link rel="stylesheet" href="../../static/css/me.css" th:href="@{/css/me.css}">
    <style>
        .error{
            color: #b96027;
        }
    </style>
</head>
<body>

<br>
<br>
<br>
<div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;">
    <div class="ur container">
        <div class="ui middle aligned center aligned grid">
            <div class="column">
                <h2 class="ui teal image header">
                    <div class="content">
                        用户登录登录
                    </div>
                </h2>
                <form class="ui large form" method="post" action="#" id="loginform" th:action="@{/user/login}">
                    <div class="ui  segment" style="position: relative;">
                        <div class="field">
                            <div class="ui left icon input">
                                <i class="user icon"></i>
                                <input type="text" name="username" placeholder="用户名">
                            </div>
                        </div>
                        <div class="field">
                            <div class="ui left icon input">
                                <i class="lock icon"></i>
                                <input type="password" name="password" placeholder="密码">
                            </div>
                        </div>
                        <div class="control-group">
                            <div class="controls" style="text-align: center">
                                <img src="/loginValidateCode" th:src="@{/user/loginValidateCode}" id="loginValidateCode" name="loginValidateCode"
                                     onclick="uploadLoginValidateCode()" class="m-margin-bottom" alt="">
                                <input type="text" id="validateCode" name="validateCode" class="form-control" style="width: 200px">
                                <p style="color: #b96027" id="validateCodeError"></p>
                            </div>
                        </div>
                        <button class="ui teal submit button">登 录</button>
                        <a href="register.html" th:href="@{/user/register}" style="position: absolute;right: 30px;bottom: 10px;">注 册</a>
                    </div>

                    <div class="ui error mini message"></div>
                    <div class="ui mini negative message" th:unless="${#strings.isEmpty(message)}" th:text="${message}">
                        用户名和密码错误
                    </div>

                </form>

            </div>
        </div>
    </div>
</div>


<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>

<script>
    $('.ui.form').form({
        fields: {
            username: {
                identifier: 'username',
                rules: [{
                    type: 'empty',
                    prompt: '请输入用户名'
                }]
            },
            password: {
                identifier: 'password',
                rules: [{
                    type: 'empty',
                    prompt: '请输入密码'
                }]
            }
        }
    });



    function uploadLoginValidateCode() {
        /*路径一定要加上项目的跟路径*/
        $("#loginValidateCode").attr("src","/user/loginValidateCode?random="+new Date().getMilliseconds());
    }



</script>

</body>
</html>

后端的代码

@Controller
@RequestMapping("/user")
public class UserLoginController {

    @Resource
    private DefaultKaptcha kaptchaProducer;

    @Autowired
    private UserMapper userMapper;

    @GetMapping
    public String Login(){
        return "user/login";
    }

    /**
     * 登录校验表单以及验证码
     * @param validateCode
     */
    @PostMapping("/login")
    public String login(@RequestParam("validateCode")String validateCode,
                        @RequestParam String username,
                        @RequestParam String password,
                        HttpSession session, RedirectAttributes attributes,
                        HttpServletRequest request){
        String loginValidateCode = request.getSession().getAttribute(LOGIN_VALIDATE_CODE).toString();
        User user = userMapper.FindUserByUsername(username);
        if (validateCode==null){
            attributes.addFlashAttribute("message","请输入验证码");
            return "redirect:/user";
        }else if (!validateCode.equals(loginValidateCode)){
            attributes.addFlashAttribute("message","验证码错误");
        }else {
            if(user == null){
                attributes.addFlashAttribute("message","用户不存在");
                return "redirect:/user";
            }else if(user.getPassword().equals(password)){
                user.setPassword(null);
                session.setAttribute("username",username);
                return "redirect:/";
            }else{
                attributes.addFlashAttribute("message","用户名或密码错误");
                return "redirect:/user";
            }
        }
        return "redirect:/user";
    }

    /**
     * 登录验证码SessionKey
     */
    public static final String LOGIN_VALIDATE_CODE = "login_validate_code";

    /**
     * 登录验证码图片
     */
    @GetMapping("/loginValidateCode")
    public void loginValidateCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        KaptchaUtils.validateCode(request,response,kaptchaProducer,LOGIN_VALIDATE_CODE);
    }

    @GetMapping("/logout")
    public String logout(HttpSession session){
        session.removeAttribute("username");
        return "redirect:/user";
    }
}

最后有什么问题请指出 谢谢大家!!!

你可能感兴趣的:(springboot 登录时 图片验证码验证)