自定义安全性高的验证机制

由于科技手段的发达,图片内容识别已经很先进,传统的数字+字符验证码你在像客户端展示的时候太迷糊了导致用户体验度差,用户看不清换来换去消耗服务器性能,太明显了跟没设验证码的意义不大,因为总有竞争者,别有用心者来捣乱,总会有智能识别验证码的方法,所以要达到魔高一尺道不限高的姿势,才立于不败之地,我不经意在某些地方看到安全性挺高的验证码验证方法,特别做了个案例供大家学习

代码贴上:
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
*由于时间有限 这只是自定义的一个小案例 您可以设计更负复杂的算法达到机器不能破解的地步
* Created by lizf on 2017/6/12.
*/
public class Validate extends HttpServlet {
private String V_CODE ;//输出到客户端
public static int WIDTH = 58;//宽度
public static int HEIGHT = 20;//高度

@Override
public void init() throws ServletException {
    super.init();
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //生成验证码
    HttpSession session =req.getSession();
    int i =  (int) (Math.random()*10);
    int j =  (int) (Math.random()*10);
    char[] ch = {'加','减','乘'};
    int operator = (int) (Math.random()*3+1);
    String sessionCode ;//存到session
    switch (ch[operator-1]){
        case '加':
            sessionCode = (i+j)+"";
            session.setAttribute("SESSION_CODE",sessionCode);
            V_CODE = i+" 加 "+j+" = ?";
            break;
        case '减':
            sessionCode = (i-j)+"";
            session.setAttribute("SESSION_CODE",sessionCode);
            V_CODE = i+" 减 "+j+" = ?";
            break;
        case '乘':
            sessionCode = (i*j)+"";
            session.setAttribute("SESSION_CODE",sessionCode);
            V_CODE = i+" 乘 "+j+" = ?";
            break;
    }
    //创建一个画板
    BufferedImage bufferedImage = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
    //创建画笔
    Graphics2D graphics2D = bufferedImage.createGraphics();
    //设置背景色
    graphics2D.setBackground(Color.blue);
    //创建区域
    graphics2D.clearRect(0,0,WIDTH,HEIGHT);
    //设置内容颜色
    graphics2D.setColor(Color.green);
    float x = 3F;//x轴
    float y = 14F;//y轴

//向画板里添加内容x y 为边距
graphics2D.drawString(V_CODE,x,y);

    //释放资源,清空缓存
    graphics2D.dispose();
    bufferedImage.flush();

    ImageIO.write(bufferedImage,"png",resp.getOutputStream()); //向客户端输出图片
}


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doPost(req,resp);
}


@Override
public void destroy() {
    super.destroy();
}

}

基于二维码验证
import com.swetake.util.Qrcode;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
*扫描二维码验证自己自定义验证玩法
* Created by lzf
*/
public class QrCodeImg extends HttpServlet {
//设定宽高
final static int HEIGHT = 236;
final static int WIDTH = 236;
final static String CONTENT = “扫码后跳转的链接或者内容”;

/*
* 生成二维码
*/
public static void getQrCodeImg() throws IOException {
//实例化一个QrCode
Qrcode qrcode = new Qrcode();
//排错率M代表15%
qrcode.setQrcodeErrorCorrect(‘M’);
//编码集
qrcode.setQrcodeEncodeMode(‘B’);
//二维码的版本
qrcode.setQrcodeVersion(15);
//创建一个画板
BufferedImage bufferedImage= new BufferedImage(WIDTH,HEIGHT,
BufferedImage.TYPE_INT_RGB);

//创建画笔
Graphics2D graphics2D = bufferedImage.createGraphics();

//设置背景色
graphics2D.setBackground(Color.white);

/创建二维码区域
graphics2D.clearRect(0,0, WIDTH, HEIGHT);

//设置内容颜色
graphics2D.setColor(Color.black);
//获取内容的字节数据,设置字符编码
byte[] contentBytes = CONTENT.getBytes(“utf-8”);

boolean[][] codeOut = qrcode.calQrcode(contentBytes);

int offset = 3;
//设置偏移量

//绘制二维码内容
for (int i= 0; i < codeOut.length; i++) {
for (int j= 0; j < codeOut.length; j++) {
if (codeOut[i][j]) {
graphics2D.fillRect(j*3+ offset,i*3+offset, 3, 3);
}
}
}
//释放资源,清空缓
graphics2D.dispose();
bufferedImage.flush();
ImageIO.write(bufferedImage,”png”,resp.getOutputStream());
//向客户端输出图片
}

为了便于编码我已打好jar包以及web项目使用案例已经放到github 项目链接
点击获取案例源码

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章