极验验证码使用
一、去极验注册账号获得ID和key
地址:https://account.geetest.com/
二、导入sdk架包
需要两个架包:java-json.jar 和 servlet-api.jar
下载地址:http://download.****.net/download/junmoxi/9949773
三、编写后台代码
StartCaptchaServlet.java (获得验证码)
- <span style="font-size:18px;">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 = "{}";
- //自定义userid
- String 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);
- }
- }</span>
- <span style="font-size:18px;">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中获取userid
- String 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());
- }
- }
- }
- </span>
GeetestConfig.java (配置文件)
- <span style="font-size:18px;">package com.lei.config;
- import javax.swing.text.StyledEditorKit.BoldAction;
- /**
- * GeetestWeb配置文件
- *
- *
- */
- public class GeetestConfig {
- // 填入自己的captcha_id和private_key
- private 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;
- }
- }
- </span>
GeetestLib.java (SDK)
- <span style="font-size:18px;">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;
- }
- }
- </span>
四、前台代码
login.jsp
- <span style="font-size:18px;"><%@ 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></span>
需要一个js文件,gt.js
运行结果
转载自:http://blog.****.net/junmoxi/article/details/77568122?locationNum=10&fps=1