Java编写极验验证码
来源:互联网 发布:三国杀淘宝 编辑:程序博客网 时间:2024/05/20 22:01
一、去极验注册账号获得ID和key
地址:https://account.geetest.com/
二、导入sdk架包
需要两个架包:java-json.jar 和 servlet-api.jar
下载地址:http://download.csdn.net/download/junmoxi/9949773
三、编写后台代码
StartCaptchaServlet.java (获得验证码)
package com.lei.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.lei.config.GeetestConfig;import com.lei.sdk.GeetestLib;public class StartCaptchaServlet extends HttpServlet {protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {GeetestLib gtSdk = new GeetestLib(GeetestConfig.getGeetest_id(), GeetestConfig.getGeetest_key(), GeetestConfig.isnewfailback());String resStr = "{}";//自定义useridString userid = "test";//进行验证预处理int gtServerStatus = gtSdk.preProcess(userid);//将服务器状态设置到session中request.getSession().setAttribute(gtSdk.gtServerStatusSessionKey, gtServerStatus);//将userid设置到session中request.getSession().setAttribute("userid", userid);resStr = gtSdk.getResponseStr();PrintWriter out = response.getWriter();out.println(resStr);}}
VerifyLoginServlet.java (验证验证码)package com.lei.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.json.JSONException;import org.json.JSONObject;import com.lei.config.GeetestConfig;import com.lei.sdk.GeetestLib;/** * 使用post方式,返回验证结果, request表单中必须包含challenge, validate, seccode */public class VerifyLoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {GeetestLib gtSdk = new GeetestLib(GeetestConfig.getGeetest_id(), GeetestConfig.getGeetest_key(), GeetestConfig.isnewfailback());String challenge = request.getParameter(GeetestLib.fn_geetest_challenge);String validate = request.getParameter(GeetestLib.fn_geetest_validate);String seccode = request.getParameter(GeetestLib.fn_geetest_seccode);//从session中获取gt-server状态int gt_server_status_code = (Integer) request.getSession().getAttribute(gtSdk.gtServerStatusSessionKey);//从session中获取useridString userid = (String)request.getSession().getAttribute("userid");int gtResult = 0;if (gt_server_status_code == 1) {//gt-server正常,向gt-server进行二次验证gtResult = gtSdk.enhencedValidateRequest(challenge, validate, seccode, userid);System.out.println(gtResult);} else {// gt-server非正常情况下,进行failback模式验证System.out.println("failback:use your own server captcha validate");gtResult = gtSdk.failbackValidateRequest(challenge, validate, seccode);System.out.println(gtResult);}if (gtResult == 1) {// 验证成功PrintWriter out = response.getWriter();JSONObject data = new JSONObject();try {data.put("status", "success");data.put("version", gtSdk.getVersionInfo());} catch (JSONException e) {e.printStackTrace();}out.println(data.toString());}else {// 验证失败JSONObject data = new JSONObject();try {data.put("status", "fail");data.put("version", gtSdk.getVersionInfo());} catch (JSONException e) {e.printStackTrace();}PrintWriter out = response.getWriter();out.println(data.toString());}}}
GeetestConfig.java (配置文件)
package com.lei.config;import javax.swing.text.StyledEditorKit.BoldAction;/** * GeetestWeb配置文件 * * */public class GeetestConfig {// 填入自己的captcha_id和private_keyprivate static final String geetest_id = "7e5a9550b98e8496127526b0459d260d";private static final String geetest_key = "354c66612d75838bfebc54f2c9c8d271";private static final boolean newfailback = true;public static final String getGeetest_id() {return geetest_id;}public static final String getGeetest_key() {return geetest_key;}public static final boolean isnewfailback() {return newfailback;}}
GeetestLib.java (SDK)
package com.lei.sdk;import java.awt.print.Printable;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.lang.reflect.GenericArrayType;import java.net.HttpURLConnection;import java.net.InetAddress;import java.net.Socket;import java.net.URL;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.HashMap;import java.util.logging.Logger;import javax.print.DocFlavor.STRING;import javax.servlet.descriptor.JspConfigDescriptor;import javax.servlet.http.HttpServletRequest;import org.json.JSONException;import org.json.JSONObject;/** * Java SDK * */public class GeetestLib {protected final String verName = "4.0";protected final String sdkLang = "java";protected final String apiUrl = "http://api.geetest.com"; protected final String registerUrl = "/register.php"; protected final String validateUrl = "/validate.php";protected final String json_format = "1"; /** * 极验验证二次验证表单数据 chllenge */public static final String fn_geetest_challenge = "geetest_challenge";/** * 极验验证二次验证表单数据 validate */public static final String fn_geetest_validate = "geetest_validate";/** * 极验验证二次验证表单数据 seccode */public static final String fn_geetest_seccode = "geetest_seccode";/** * 公钥 */private String captchaId = "";/** * 私钥 */private String privateKey = "";/** * 是否开启新的failback */private boolean newFailback = false;/** * 返回字符串 */private String responseStr = "";/** * 调试开关,是否输出调试日志 */public boolean debugCode = true;/** * 极验验证API服务状态Session Key */public String gtServerStatusSessionKey = "gt_server_status";/** * 标记字段 */public String userId = "";/** * 标记验证模块所应用的终端类型 */public String clientType = "";/** * 标记用户请求验证时所携带的IP */public String ipAddress = "";/** * 带参数构造函数 * * @param captchaId * @param privateKey */public GeetestLib(String captchaId, String privateKey, boolean newFailback) {this.captchaId = captchaId;this.privateKey = privateKey;this.newFailback = newFailback;}/** * 获取本次验证初始化返回字符串 * * @return 初始化结果 */public String getResponseStr() {return responseStr;}public String getVersionInfo() {return verName;}/** * 预处理失败后的返回格式串 * * @return */private String getFailPreProcessRes() {Long rnd1 = Math.round(Math.random() * 100);Long rnd2 = Math.round(Math.random() * 100);String md5Str1 = md5Encode(rnd1 + "");String md5Str2 = md5Encode(rnd2 + "");String challenge = md5Str1 + md5Str2.substring(0, 2);JSONObject jsonObject = new JSONObject();try {jsonObject.put("success", 0);jsonObject.put("gt", this.captchaId);jsonObject.put("challenge", challenge);jsonObject.put("new_captcha", this.newFailback);} catch (JSONException e) {gtlog("json dumps error");}return jsonObject.toString();}/** * 预处理成功后的标准串 * */private String getSuccessPreProcessRes(String challenge) {gtlog("challenge:" + challenge);JSONObject jsonObject = new JSONObject();try {jsonObject.put("success", 1);jsonObject.put("gt", this.captchaId);jsonObject.put("challenge", challenge);} catch (JSONException e) {gtlog("json dumps error");}return jsonObject.toString();}/** * 验证初始化预处理 * * @return 1表示初始化成功,0表示初始化失败 */public int preProcess() {if (registerChallenge() != 1) {this.responseStr = this.getFailPreProcessRes();return 0;}return 1;}/** * 验证初始化预处理 * * @param userid * @return 1表示初始化成功,0表示初始化失败 */public int preProcess(String userid){this.userId = userid;return this.preProcess();}/** * 用captchaID进行注册,更新challenge * * @return 1表示注册成功,0表示注册失败 */private int registerChallenge() {try {String getUrl = apiUrl + registerUrl + "?";String param = "gt=" + this.captchaId + "&json_format=" + this.json_format;if (this.userId != ""){param = param + "&user_id=" + this.userId;this.userId = "";}if (this.clientType != ""){param = param + "&client_type=" + this.clientType;this.clientType = "";}if (this.ipAddress != ""){param = param + "&ip_address=" + this.ipAddress;this.ipAddress = "";}gtlog("GET_URL:" + getUrl + param);String result_str = readContentFromGet(getUrl + param);if (result_str == "fail"){gtlog("gtServer register challenge failed");return 0;}gtlog("result:" + result_str);JSONObject jsonObject = new JSONObject(result_str); String return_challenge = jsonObject.getString("challenge");gtlog("return_challenge:" + return_challenge);if (return_challenge.length() == 32) {this.responseStr = this.getSuccessPreProcessRes(this.md5Encode(return_challenge + this.privateKey)); return 1; }else {gtlog("gtServer register challenge error");return 0;}} catch (Exception e) {gtlog(e.toString());gtlog("exception:register api");}return 0;}/** * 判断一个表单对象值是否为空 * * @param gtObj * @return */protected boolean objIsEmpty(Object gtObj) {if (gtObj == null) {return true;}if (gtObj.toString().trim().length() == 0) {return true;}return false;}/** * 检查客户端的请求是否合法,三个只要有一个为空,则判断不合法 * * @param request * @return */private boolean resquestIsLegal(String challenge, String validate, String seccode) {if (objIsEmpty(challenge)) {return false;}if (objIsEmpty(validate)) {return false;}if (objIsEmpty(seccode)) {return false;}return true;}/** * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果 * * @param challenge * @param validate * @param seccode * @return 验证结果,1表示验证成功0表示验证失败 */public int enhencedValidateRequest(String challenge, String validate, String seccode) {if (!resquestIsLegal(challenge, validate, seccode)) {return 0;}gtlog("request legitimate");String postUrl = this.apiUrl + this.validateUrl;String param = String.format("challenge=%s&validate=%s&seccode=%s&json_format=%s", challenge, validate, seccode, this.json_format); String response = "";try {if (validate.length() <= 0) {return 0;}if (!checkResultByPrivate(challenge, validate)) {return 0;}gtlog("checkResultByPrivate");response = readContentFromPost(postUrl, param);gtlog("response: " + response);} catch (Exception e) {e.printStackTrace();}String return_seccode = "";try {JSONObject return_map = new JSONObject(response);return_seccode = return_map.getString("seccode");gtlog("md5: " + md5Encode(return_seccode));if (return_seccode.equals(md5Encode(seccode))) {return 1;} else {return 0;}} catch (JSONException e) {gtlog("json load error");return 0;}}/** * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果 * * @param challenge * @param validate * @param seccode * @param userid * @return 验证结果,1表示验证成功0表示验证失败 */public int enhencedValidateRequest(String challenge, String validate, String seccode, String userid) {this.userId = userid;return this.enhencedValidateRequest(challenge, validate, seccode);}/** * failback使用的验证方式 * * @param challenge * @param validate * @param seccode * @return 验证结果,1表示验证成功0表示验证失败 */public int failbackValidateRequest(String challenge, String validate, String seccode) {gtlog("in failback validate");if (!resquestIsLegal(challenge, validate, seccode)) {return 0;}gtlog("request legitimate");return 1;}/** * 输出debug信息,需要开启debugCode * * @param message */public void gtlog(String message) {if (debugCode) {System.out.println("gtlog: " + message);}}protected boolean checkResultByPrivate(String challenge, String validate) {String encodeStr = md5Encode(privateKey + "geetest" + challenge);return validate.equals(encodeStr);}/** * 发送GET请求,获取服务器返回结果 * * @param getURL * @return 服务器返回结果 * @throws IOException */private String readContentFromGet(String URL) throws IOException {URL getUrl = new URL(URL);HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();connection.setConnectTimeout(2000);// 设置连接主机超时(单位:毫秒)connection.setReadTimeout(2000);// 设置从主机读取数据超时(单位:毫秒)// 建立与服务器的连接,并未发送数据connection.connect();if (connection.getResponseCode() == 200) {// 发送数据到服务器并使用Reader读取返回的数据StringBuffer sBuffer = new StringBuffer();InputStream inStream = null;byte[] buf = new byte[1024];inStream = connection.getInputStream();for (int n; (n = inStream.read(buf)) != -1;) {sBuffer.append(new String(buf, 0, n, "UTF-8"));}inStream.close();connection.disconnect();// 断开连接 return sBuffer.toString();}else {return "fail";}}/** * 发送POST请求,获取服务器返回结果 * * @param getURL * @return 服务器返回结果 * @throws IOException */private String readContentFromPost(String URL, String data) throws IOException {gtlog(data);URL postUrl = new URL(URL);HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();connection.setConnectTimeout(2000);// 设置连接主机超时(单位:毫秒)connection.setReadTimeout(2000);// 设置从主机读取数据超时(单位:毫秒)connection.setRequestMethod("POST");connection.setDoInput(true);connection.setDoOutput(true);connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");// 建立与服务器的连接,并未发送数据connection.connect(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream(), "utf-8"); outputStreamWriter.write(data); outputStreamWriter.flush(); outputStreamWriter.close();if (connection.getResponseCode() == 200) {// 发送数据到服务器并使用Reader读取返回的数据StringBuffer sBuffer = new StringBuffer();InputStream inStream = null;byte[] buf = new byte[1024];inStream = connection.getInputStream();for (int n; (n = inStream.read(buf)) != -1;) {sBuffer.append(new String(buf, 0, n, "UTF-8"));}inStream.close();connection.disconnect();// 断开连接 return sBuffer.toString();}else {return "fail";}}/** * md5 加密 * * @time 2014年7月10日 下午3:30:01 * @param plainText * @return */private String md5Encode(String plainText) {String re_md5 = new String();try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(plainText.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)buf.append("0");buf.append(Integer.toHexString(i));}re_md5 = buf.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return re_md5;}}
四、前台代码
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";%><!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>gt-node-sdk-demo</title> <style> body { margin: 50px 0; text-align: center; font-family: "PingFangSC-Regular", "Open Sans", Arial, "Hiragino Sans GB", "Microsoft YaHei", "STHeiti", "WenQuanYi Micro Hei", SimSun, sans-serif; } .inp { border: 1px solid #cccccc; border-radius: 2px; padding: 0 10px; width: 278px; height: 40px; font-size: 18px; } .btn { border: 1px solid #cccccc; border-radius: 2px; width: 100px; height: 40px; font-size: 16px; color: #666; cursor: pointer; background: white linear-gradient(180deg, #ffffff 0%, #f3f3f3 100%); } .btn:hover { background: white linear-gradient(0deg, #ffffff 0%, #f3f3f3 100%) } #captcha1, #captcha2 { width: 300px; display: inline-block; } .show { display: block; } .hide { display: none; } #notice1, #notice2 { color: red; } label { vertical-align: top; display: inline-block; width: 80px; text-align: right; } #wait1, #wait2 { text-align: left; color: #666; margin: 0; } </style></head><body><h1>极验验证SDKDemo</h1><hr><form action="gt/ajax-validate1" method="post"> <h2>大图点击Demo,使用表单进行二次验证</h2> <br> <div> <label for="username1">用户名:</label> <input class="inp" id="username1" type="text" value="极验验证"> </div> <br> <div> <label for="password1">密码:</label> <input class="inp" id="password1" type="password" value="123456"> </div> <br> <div> <label>完成验证:</label> <div id="captcha1"> <p id="wait1" class="show">正在加载验证码......</p> </div> </div> <br> <p id="notice1" class="hide">请先完成验证</p> <input class="btn" id="submit1" type="submit" value="提交"></form><!-- 注意,验证码本身是不需要 jquery 库,此处使用 jquery 仅为了在 demo 使用,减少代码量 --><script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script><!-- 引入 gt.js,既可以使用其中提供的 initGeetest 初始化函数 --><script src="<%=request.getContextPath() %>/gt.js"></script><script> var handler1 = function (captchaObj) { $("#submit1").click(function (e) { var result = captchaObj.getValidate(); if (!result) { $("#notice1").show(); setTimeout(function () { $("#notice1").hide(); }, 2000); e.preventDefault(); } }); // 将验证码加到id为captcha的元素里,同时会有三个input的值用于表单提交 captchaObj.appendTo("#captcha1"); captchaObj.onReady(function () { $("#wait1").hide(); }); // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html }; $.ajax({ url: "gt/register1?t=" + (new Date()).getTime(), // 加随机数防止缓存 type: "get", dataType: "json", success: function (data) { // 调用 initGeetest 初始化参数 // 参数1:配置参数 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它调用相应的接口 initGeetest({ gt: data.gt, challenge: data.challenge, new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机 offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注 product: "float", // 产品形式,包括:float,popup width: "100%" // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handler1); } });</script><br><br><hr><form> <h2>滑动demo,使用ajax进行二次验证</h2> <br> <div> <label for="username2">用户名:</label> <input class="inp" id="username2" type="text" value="极验验证"> </div> <br> <div> <label for="password2">密码:</label> <input class="inp" id="password2" type="password" value="123456"> </div> <br> <div> <label>完成验证:</label> <div id="captcha2"> <p id="wait2" class="show">正在加载验证码......</p> </div> </div> <br> <p id="notice2" class="hide">请先完成验证</p> <input class="btn" id="submit2" type="submit" value="提交"></form><script> var handler2 = function (captchaObj) { $("#submit2").click(function (e) { var result = captchaObj.getValidate(); if (!result) { $("#notice2").show(); setTimeout(function () { $("#notice2").hide(); }, 2000); } else { $.ajax({ url: 'gt/ajax-validate2', type: 'POST', dataType: 'json', data: { username: $('#username2').val(), password: $('#password2').val(), geetest_challenge: result.geetest_challenge, geetest_validate: result.geetest_validate, geetest_seccode: result.geetest_seccode }, success: function (data) { if (data.status === 'success') { alert('登录成功'); } else if (data.status === 'fail') { alert('登录失败'); } } }) } e.preventDefault(); }); // 将验证码加到id为captcha的元素里,同时会有三个input的值用于表单提交 captchaObj.appendTo("#captcha2"); captchaObj.onReady(function () { $("#wait2").hide(); }); // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html }; $.ajax({ url: "gt/register2?t=" + (new Date()).getTime(), // 加随机数防止缓存 type: "get", dataType: "json", success: function (data) { // 调用 initGeetest 初始化参数 // 参数1:配置参数 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它调用相应的接口 initGeetest({ gt: data.gt, challenge: data.challenge, new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机 offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注 product: "popup", // 产品形式,包括:float,popup width: "100%" // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handler2); } });</script></body></html>
需要一个js文件,gt.js
运行结果
下载地址和Demo都可以在下面的地址下载 到
http://download.csdn.net/download/junmoxi/9949773
阅读全文
0 0
- Java编写极验验证码
- Java编写验证码
- Java编写验证码
- Java 编写验证码
- JAVA编写的验证码
- 用Java编写验证码
- Java验证码的编写
- java验证码的编写和校验
- java生成验证码配置及编写
- java编写简单漂亮的验证码
- Java编写生成的验证码
- 验证码的编写
- 验证码的编写
- 验证码编写
- 验证码编写
- Servlet编写验证码
- 验证码的编写
- JavaScript编写验证码
- 关于mysql安装与配置的笔记
- 初学Linux--编辑环境1(vim、gcc、make)
- EBI (外部总线接口) 控制I80接口LCD屏
- 版本号
- 使用Linux服务器发送邮件
- Java编写极验验证码
- Packet Tracer 5.0实验(三) 交换机划分VLAN配置
- Tablayout
- 那些年我们一起清除过的浮动(BFC特性)
- Objective-C与JavaScript交互的那些事
- 推荐系统实践-好的推荐系统
- ImageView嵌套进ScrollView,发现图片总是存在间隔
- php万年历
- Gson将字符串转map时,int、long默认为double类型