一、什麼是圖檔驗證碼?
可以參考下面這張圖:

我們在一些網站登陸的時候,經常需要填寫以上圖檔的資訊。
這種圖檔驗證方式是我們最常見的形式,它可以有效的防範惡意攻擊者采用惡意工具,來進行竊取使用者的密碼
接下來将講正題啦!
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("失敗啦");
}
});
}
JAVA實作圖檔驗證
JAVA實作圖檔驗證
好了,這就是基本上實作的步驟,最後再上幾張實作效果圖↑↑↑↑↑
@注:本部落格僅為個人學習筆記。 所屬人:Yuan