一、什么是图片验证码?
可以参考下面这张图:
我们在一些网站登陆的时候,经常需要填写以上图片的信息。
这种图片验证方式是我们最常见的形式,它可以有效的防范恶意攻击者采用恶意工具,来进行窃取用户的密码
接下来将讲正题啦!
1.首先得有一个生成图片验证码的实体类
package com.zhetian.www.util; import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random; /**
* @Copyright (C)遮天网络有限公司
* @Author: YUAN HUAI XING
* @qq联系方式: 11234013
* @Date 2020/4/5 18:09
* @Descripthion:
**/ public class ImageVerificationCodeUtil {
private int weight = 100; //验证码图片的长和宽
private int height = 40;
private String text; //用来保存验证码的文本内容
private Random r = new Random(); //获取随机数对象
//private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"}; //字体数组
//字体数组
private String[] fontNames = {"Georgia"};
//验证码数组
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; /**
* 获取随机的颜色
*
* @return
*/
private Color randomColor() {
int r = this.r.nextInt(225); //这里为什么是225,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。
int g = this.r.nextInt(225);
int b = this.r.nextInt(225);
return new Color(r, g, b); //返回一个随机颜色
} /**
* 获取随机字体
*
* @return
*/
private Font randomFont() {
int index = r.nextInt(fontNames.length); //获取随机的字体
String fontName = fontNames[index];
int style = r.nextInt(4); //随机获取字体的样式,0是无样式,1是加粗,2是斜体,3是加粗加斜体
int size = r.nextInt(10) + 24; //随机获取字体的大小
return new Font(fontName, style, size); //返回一个随机的字体
} /**
* 获取随机字符
*
* @return
*/
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
} /**
* 画干扰线,验证码干扰线用来防止计算机解析图片
*
* @param image
*/
private void drawLine(BufferedImage image) {
int num = r.nextInt(10); //定义干扰线的数量
Graphics2D g = (Graphics2D) image.getGraphics();
for (int i = 0; i < num; i++) {
int x1 = r.nextInt(weight);
int y1 = r.nextInt(height);
int x2 = r.nextInt(weight);
int y2 = r.nextInt(height);
g.setColor(randomColor());
g.drawLine(x1, y1, x2, y2);
}
} /**
* 创建图片的方法
*
* @return
*/
private BufferedImage createImage() {
//创建图片缓冲区
BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics2D g = (Graphics2D) image.getGraphics();
//设置背景色随机
g.setColor(new Color(255, 255, r.nextInt(245) + 10));
g.fillRect(0, 0, weight, height);
//返回一个图片
return image;
} /**
* 获取验证码图片的方法
*
* @return
*/
public BufferedImage getImage() {
BufferedImage image = createImage();
Graphics2D g = (Graphics2D) image.getGraphics(); //获取画笔
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) //画四个字符即可
{
String s = randomChar() + ""; //随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画
sb.append(s); //添加到StringBuilder里面
float x = i * 1.0F * weight / 4; //定义字符的x坐标
g.setFont(randomFont()); //设置字体,随机
g.setColor(randomColor()); //设置颜色,随机
g.drawString(s, x, height - 5);
}
this.text = sb.toString();
drawLine(image);
return image;
} /**
* 获取验证码文本的方法
*
* @return
*/
public String getText() {
return text;
} public static void output(BufferedImage image, OutputStream out) throws IOException //将验证码图片写出的方法
{
ImageIO.write(image, "JPEG", out);
} }
2.在控制器中把图片响应给前端页面(ssm框架)
/**
* 图片随机码
* @param request
* @param response
* @throws IOException
*/
@RequestMapping("/getVerifiCode")
public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
/*
1.生成验证码
2.把验证码上的文本存在session中
3.把验证码图片发送给客户端
*/
ImageVerificationCodeUtil ivc = new ImageVerificationCodeUtil(); //用我们的验证码类,生成验证码类对象
BufferedImage image = ivc.getImage(); //获取验证码
String text = ivc.getText(); //获取随机码
HttpSession session = request.getSession();
session.setAttribute("imgcode", text); //将随机码的文本存在session中
System.out.println("文字随机码:"+text);
ImageVerificationCodeUtil.output(image, response.getOutputStream());//将验证码图片响应给客户端
}
3、从session获得验证码字符(ssm框架)
/**
* 登陆功能:接收用户输入的用户名跟密码(接收参数)
* @param loginUser
* @return
*/
@RequestMapping("/pageData")
@ResponseBody
public Result pageData(LoginUser loginUser,String code,HttpServletRequest request){
HttpSession session = request.getSession();
//获取随机数
String imgcode = (String)session.getAttribute("imgcode");
//调用业务方法
Result<LoginUser> result= loginUserService.loginUserByuserName(loginUser, code,imgcode);
return result;
}
4、业务层(Service)
/**
* 获取用户输入的用户名与数据库进行对比是否一致
* 如果一致在获取密码对比是否一致
* 都一致再对比图片验证码与用户输入的是否一致
* @param loginUser
* @return
*/
@Override
public Result loginUserByuserName(LoginUser loginUser,String code,String imgcode) {
Result<LoginUser> result = new Result<>();
String userName = loginUser.getUserName();
LoginUser loginUser1 = loginUserDao.loginUserByuserName(userName);
if (code != null && code.equals(imgcode)) {
if (loginUser1 != null) {
String password = loginUser.getPassword();
String password1 = loginUser1.getPassword();
if (password != null && password1 != null && password1.equals(password)) {
result.setCode("0000");
result.setData(loginUser);
return result;
} else {
result.setCode("0001");
result.setMsg("用户名或密码错误!请检查后重新登陆!");
result.setSuccess(false);
return result;
}
} else {
result.setCode("0002");
result.setMsg("用户名不存在!请检查用户名后重新登陆!");
result.setSuccess(false);
return result;
}
}else {
result.setCode("0005");
result.setMsg("验证码不正确!");
result.setSuccess(false);
return result;
} }
5、前端代码
<div class="form-group">
<%--<label for="password">请输入验证码--%>
</label>
<input id="code" type="text" class="form-control" name="code" width="400px" placeholder="请输入验证码">
<a href="javascript:getVerifiCode()">
<img id="yzm_img" style="cursor:pointer;width: 100px;height: 40px;margin: 0px 0 0 5px;
border-radius: 3px;"
title="点击刷新验证码" src="/login/getVerifiCode" />
</a>
</div>
function pageData() {
var code=$("#code").val();
var userName=$("#userName").val();
var password=$("#password").val();
var aa = $("input[type='checkbox']").is(":checked");//获取选中状态
if(userName == ''){
alert("请输入用户名。");
return;
}
if(password == ''){
alert("请输入密码。");
return;
}
if(aa==true){
setCookie(); //调用设置Cookie的方法
}else if(aa==false){
setCookie(); //调用设置Cookie的方法
} var params = {
userName:userName,
password:password,
code:code
};
var url = '/login/pageData';
jQuery.ajax({
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
url: url,
data: params,
dataType: 'json',
success: function (data) {
// alert("成功啦");
var code=data.code;
if (code=="0000"){
alert("登陆成功!")
location.href="/tick/list";
} else if(code=="0001"){
alert("登陆提示:"+data.msg);
}else if(code=="0002"){
alert("登陆提示:"+data.msg);
}else if(code=="0005"){
alert("登陆提示:"+data.msg);
}else {
alert("未知异常!");
} },
error: function (data) {
alert("失败啦");
}
});
}
好了,这就是基本上实现的步骤,最后再上几张实现效果图↑↑↑↑↑
@注:本博客仅为个人学习笔记。 所属人:Yuan