Kaptcha验证码组件
Kaptcha是谷歌开源的可高度配置的实用验证码生成工具。
通过Kaptcha可阻拦大多数机器人脚本操作
Kaptcha典型应用于注册、登录、重要信息提交等用户交互。
Kaptcha使用步骤
Kaptcha配置验证码生成参数。
开发KaptchaController生成验证码图片。
将前台输入验证码与session保存的验证码进行比对。
代码演示
首先打开pom.xml文件,引入Kaptcha依赖
<dependency>
<groupId>com.github.pengglegroupId>
<artifactId>kaptchaartifactId>
<version>2.3.2version>
dependency>
打开applicationContext.xml添加Kaptcha配置
<bean id="kaptchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">noprop>
<prop key="kaptcha.image.width">120prop>
<prop key="kaptcha.textproducer.font.color">blueprop>
<prop key="kaptcha.textproducer.font.size">40prop>
<prop key="kaptcha.textproducer.char.length">4prop>
props>
constructor-arg>
bean>
property>
bean>
然后在com.ql.reader.controller包下创建KaptchaController.java类,编写获取验证码的方法
package com.ql.reader.controller;
import com.google.code.kaptcha.Producer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
@Controller
public class KaptchaController {
@Resource
private Producer kaptchaProducer;
@GetMapping("/verify_code")
public void createVerifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
//响应立即过期
response.setDateHeader("Expires", 0);
//不缓存任何图片数据
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.setHeader("Cache-Control", "post-check=0,pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/png");
//生成验证码字符文本
String verifyCode = kaptchaProducer.createText();
request.getSession().setAttribute("kaptchaVerifyCode", verifyCode);
System.out.println(request.getSession().getAttribute("kaptchaVerifyCode"));
BufferedImage image = kaptchaProducer.createImage(verifyCode);//创建验证码图片
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "png", out);
out.flush();
out.close();
}
}
运行项目,在浏览器中访问http://localhost:8080/verify_code如出现验证码图片则进行下一步。
下面我们开发注册功能,在com.ql.reader.controller包下创建会员控制器MemberController.java
package com.ql.reader.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MemberController {
@GetMapping("/register.html")
public ModelAndView showRegister(){
return new ModelAndView("/register");
}
}
在src/main/webapp/WEB-INF/ftl目录下创建register.ftl文件,内容为:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>会员注册-书评网title>
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="/resources/bootstrap/bootstrap.css">
<link rel="stylesheet" href="/resources/raty/lib/jquery.raty.css">
<script src="/resources/jquery.3.3.1.min.js">script>
<script src="/resources/bootstrap/bootstrap.min.js">script>
<style>
.container {
padding: 0px;
margin: 0px;
}
.row {
padding: 0px;
margin: 0px;
}
.col- * {
padding: 0px;
}
.description p {
text-indent: 2em;
}
.description img {
width: 100%;
}
style>
head>
<body>
<div class="container ">
<nav class="navbar navbar-light bg-white shadow">
<ul class="nav">
<li class="nav-item">
<a href="/" style="color: #aaa;font-weight: bold">
书评网
a>
li>
ul>
nav>
<div class="container mt-2 p-2 m-0">
<form id="frmLogin">
<div class="passport bg-white">
<h4 class="float-left">会员注册h4>
<h6 class="float-right pt-2"><a href="/login.html">会员登录a>h6>
<div class="clearfix">div>
<div class="alert d-none mt-2" id="tips" role="alert">
div>
<div class="input-group mt-2 ">
<input type="text" id="username" name="username" class="form-control p-4" placeholder="请输入用户名">
div>
<div class="input-group mt-4 ">
<input id="password" name="password" class="form-control p-4" placeholder="请输入密码" type="password">
div>
<div class="input-group mt-4 ">
<input type="text" id="nickname" name="nickname" class="form-control p-4" placeholder="请输入用户名"
>
div>
<div class="input-group mt-4 ">
<div class="col-5 p-0">
<input type="text" id="verifyCode" name="vc" class="form-control p-4" placeholder="验证码">
div>
<div class="col-4 p-0 pl-2 pt-0">
<img id="imgVerifyCode" src="/verify_code"
style="width: 120px;height:50px;cursor: pointer">
div>
div>
<a id="btnSubmit" class="btn btn-success btn-block mt-4 text-white pt-3 pb-3">注 册a>
div>
form>
div>
div>
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
您已注册成功
div>
<div class="modal-footer">
<a href="/login.html" type="button" class="btn btn-primary">去登录a>
div>
div>
div>
div>
<script>
//控制错误信息的显示与隐藏
function showTips(isShow, css, text) {
if (isShow) {
$("#tips").removeClass("d-none")
$("#tips").hide();
$("#tips").addClass(css);
$("#tips").text(text);
$("#tips").fadeIn(200);
} else {
$("#tips").text("");
$("#tips").fadeOut(200);
$("#tips").removeClass();
$("#tips").addClass("alert")
}
}
//重新发送请求,刷新验证码
function reloadVerifyCode(){
//请在这里实现刷新验证码
$("#imgVerifyCode").attr("src","/verify_code?ts=" + new Date().getTime());
}
//点击验证码图片刷新验证码
$("#imgVerifyCode").click(function () {
reloadVerifyCode();
});
//点击提交按钮,向/registe发起ajax请求
//提交请求包含四个参数
//vc:前台输入验证码 username:用户名 password:密码 nickname:昵称
$("#btnSubmit").click(function () {
//表单校验
var username = $.trim($("#username").val());
var regex = /^.{6,10}$/;
if (!regex.test(username)) {
showTips(true, "alert-danger", "用户名请输入正确格式(6-10位)");
return;
} else {
showTips(false);
}
var password = $.trim($("#password").val());
if (!regex.test(password)) {
showTips(true, "alert-danger", "密码请输入正确格式(6-10位)");
return;
} else {
showTips(false);
}
$btnReg = $(this);
$btnReg.text("正在处理...");
$btnReg.attr("disabled", "disabled");
//发送ajax请求
$.ajax({
url: "/registe",
type: "post",
dataType: "json",
data: $("#frmLogin").serialize(),
success: function (data) {
//结果处理,根据服务器返回code判断服务器处理状态
//服务器要求返回JSON格式:
//{"code":"0","msg":"处理消息"}
console.info("服务器响应:" , data);
if (data.code == "0") {
//显示注册成功对话框
$("#exampleModalCenter").modal({});
$("#exampleModalCenter").modal("show");
} else {
//服务器校验异常,提示错误信息
showTips(true, "alert-danger", data.msg);
reloadVerifyCode();
$btnReg.text("注 册");
$btnReg.removeAttr("disabled");
}
}
});
return false;
});
script>
body>
html>
运行项目,在浏览器中输入http://localhost:8080/register.html验证码部分就能正常展示了。
下面编写点击注册时后台验证验证码的代码,打开MemberController.java添加方法
@PostMapping("/registe")
@ResponseBody
public Map registe(String vc, String username, String password, String nickname, HttpServletRequest request){
//正确验证码
String verifyCode = (String) request.getSession().getAttribute("kaptchaVerifyCode");
//验证码对比
Map result = new HashMap();
if (vc==null || verifyCode==null || !vc.equalsIgnoreCase(verifyCode)){
result.put("code", "VC01");
result.put("msg", "验证码错误");
}else{
result.put("code", "0");
result.put("msg", "success");
}
return result;
}
运行项目,浏览器访问http://localhost:8080/register.html测试验证码校验。