自定義安全性高的驗證機制

由於科技手段的發達,圖片內容識別已經很先進,傳統的數字+字符驗證碼你在像客戶端展示的時候太迷糊了導致用戶體驗度差,用戶看不清換來換去消耗服務器性能,太明顯了跟沒設驗證碼的意義不大,因爲總有競爭者,別有用心者來搗亂,總會有智能識別驗證碼的方法,所以要達到魔高一尺道不限高的姿勢,才立於不敗之地,我不經意在某些地方看到安全性挺高的驗證碼驗證方法,特別做了個案例供大家學習

代碼貼上:
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 項目鏈接
點擊獲取案例源碼

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