突发奇想把六位验证码登录换成滑动,后又想要加拼图解锁,苦于js技术与css技术实在是差,于是在网上找到了这个
网易云盾:点击打开链接
注册后登陆,找到下面我的产品,创建一个免费的验证码产品
然后点击创建产品操作栏的查看详情
jsp页面代码如下:
易盾验证码-DEMO
package com.lft.pay.util;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.apache.commons.codec.digest.DigestUtils;
/**
* 网易云盾验证码
* @author Koow
* 参数设置
*/
public class WYyzm {
private final String key="填你自己的"; //密钥
private String url="http://c.dun.163yun.com/api/v1/verify"; //请求地址
private String captchaId="填你自己的"; //验证码ID
private String validate=""; //提交二次校验的验证数据,即NECaptchaValidate值
private String user=""; //用户信息,值可为空
private String secretId="填你自己的"; //密钥对id
private String version="v1"; //版本信息,固定值v1
private String timestamp=System.currentTimeMillis()+""; //当前时间戳的毫秒值,例1480395193000
private String nonce=new Random().nextInt(10)+""; //随机正整数,与 timestamp 联合起来,用于防止重放攻击
private String signature=""; //签名信息,见签名计算
private Map params=new HashMap();
public WYyzm(String validate,String user){
this.validate=validate;
this.user=user;
this.params.put("captchaId", captchaId);
this.params.put("validate", validate);
this.params.put("user", user);
this.params.put("secretId", secretId);
this.params.put("version", version);
this.params.put("timestamp", timestamp);
this.params.put("nonce", nonce);
}
/**
* 生成签名信息
* @param secretKey 产品私钥
* @param params 接口请求参数名和参数值map,不包括signature参数名
* @return
*/
public void genSignature() throws Exception{
// 1. 参数名按照ASCII码表升序排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 2. 按照排序拼接参数名与参数值
StringBuilder sb = new StringBuilder();
for (String key : keys) {
sb.append(key).append(params.get(key));
}
// 3. 将secretKey拼接到最后
sb.append(this.key);
// 4. MD5是128位长度的摘要算法,转换为十六进制之后长度为32字符
signature=DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
}
public String getValidate() {
return validate;
}
public void setValidate(String validate) {
this.validate = validate;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getUrl() {
return url;
}
public String getCaptchaId() {
return captchaId;
}
public String getSecretId() {
return secretId;
}
public String getVersion() {
return version;
}
public String getTimestamp() {
return timestamp;
}
public String getNonce() {
return nonce;
}
public String getSignature() {
return signature;
}
public String getKey() {
return key;
}
}
package com.lft.pay.util;
/**
* 密钥对
* Created by captcha_dev on 16-11-10.
*/
public class NESecretPair {
public final String secretId;
public final String secretKey;
/**
* 构造函数
* @param secretId 密钥对id
* @param secretKey 密钥对key
*/
public NESecretPair(String secretId, String secretKey) {
this.secretId = secretId;
this.secretKey = secretKey;
}
}
package com.lft.pay.util;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
/**
* 二次验证
* Created by captcha_dev on 16-9-29.
*/
public class NECaptchaVerifier {
public static final String VERIFY_API = "http://c.dun.163yun.com/api/v1/verify"; // verify接口地址
public static final String REQ_VALIDATE = "NECaptchaValidate"; // 二次验证带过来的validate
private static final String VERSION = "v1";
private String captchaId = ""; // 验证码id
private NESecretPair secretPair = null; // 密钥对
public NECaptchaVerifier(String captchaId, NESecretPair secretPair) {
Validate.notBlank(captchaId, "captchaId为空");
Validate.notNull(secretPair, "secret为null");
Validate.notBlank(secretPair.secretId, "secretId为空");
Validate.notBlank(secretPair.secretKey, "secretKey为空");
this.captchaId = captchaId;
this.secretPair = secretPair;
}
/**
* 二次验证
*
* @param validate 验证码组件提交上来的NECaptchaValidate值
* @param user 用户
* @return
*/
public boolean verify(String validate, String user) {
if (StringUtils.isEmpty(validate)) {
return false;
}
Map params = new HashMap();
params.put("captchaId", captchaId);
params.put("validate", validate);
params.put("user", user);
// 公共参数
params.put("secretId", secretPair.secretId);
params.put("version", VERSION);
params.put("timestamp", String.valueOf(System.currentTimeMillis()));
params.put("nonce", String.valueOf(ThreadLocalRandom.current().nextInt()));
// 计算请求参数签名信息
String signature = sign(secretPair.secretKey, params);
params.put("signature", signature);
String resp = HttpClient4Utils.sendPost(VERIFY_API, params);
System.out.println("resp = " + resp);
return verifyRet(resp);
}
/**
* 生成签名信息
*
* @param secretKey 验证码私钥
* @param params 接口请求参数名和参数值map,不包括signature参数名
* @return
*/
public static String sign(String secretKey, Map params) {
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
StringBuffer sb = new StringBuffer();
for (String key : keys) {
sb.append(key).append(params.get(key));
}
sb.append(secretKey);
try {
return DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();// 一般编码都支持的。。
}
return null;
}
/**
* 验证返回结果
*
* @param resp
* @return
*/
private boolean verifyRet(String resp) {
if (StringUtils.isEmpty(resp)) {
return false;
}
try {
JSONObject j = JSONObject.parseObject(resp);
return j.getBoolean("result");
} catch (Exception e) {
return false;
}
}
}
package com.lft.pay.util;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by captcha_dev on 16-10-9.
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = -3185301474503659058L;
private static final String captchaId = "YOUR_CAPTCHA_ID"; // 验证码id
private static final String secretId = "YOUR_SECRET_ID"; // 密钥对id
private static final String secretKey = "YOUR_SECRET_KEY"; // 密钥对key
private final NECaptchaVerifier verifier = new NECaptchaVerifier(captchaId, new NESecretPair(secretId, secretKey));
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String validate = request.getParameter(NECaptchaVerifier.REQ_VALIDATE); // 从请求体里获得验证码validate数据
String user = "{'id':'123456'}";
boolean isValid = verifier.verify(validate, user); // 发起二次校验
System.out.println("validate = " + validate + ", isValid = " + isValid);
if (isValid) {
response.sendRedirect("/success.jsp");
} else {
response.sendRedirect("/fail.jsp");
}
}
}
/*
* @(#) HttpClientUtils.java 2016年2月3日
*
* Copyright 2010 NetEase.com, Inc. All rights reserved.
*/
package com.lft.pay.util;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* HttpClient工具类
*
* @author captcha_dev
* @version 2016年2月3日
*/
public class HttpClient4Utils {
private static HttpClient defaultClient = createHttpClient(20, 20, 5000, 5000, 3000);
/**
* 实例化HttpClient
*
* @param maxTotal
* @param maxPerRoute
* @param socketTimeout
* @param connectTimeout
* @param connectionRequestTimeout
* @return
*/
public static HttpClient createHttpClient(int maxTotal, int maxPerRoute, int socketTimeout, int connectTimeout,
int connectionRequestTimeout) {
RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(maxTotal);
cm.setDefaultMaxPerRoute(maxPerRoute);
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
.setDefaultRequestConfig(defaultRequestConfig).build();
return httpClient;
}
/**
* 发送post请求
*
* @param httpClient
* @param url 请求地址
* @param params 请求参数
* @param encoding 编码
* @return
*/
public static String sendPost(HttpClient httpClient, String url, Map params, Charset encoding) {
String resp = "";
HttpPost httpPost = new HttpPost(url);
if (params != null && params.size() > 0) {
List formParams = new ArrayList();
Iterator> itr = params.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = itr.next();
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(formParams, encoding);
httpPost.setEntity(postEntity);
}
CloseableHttpResponse response = null;
try {
response = (CloseableHttpResponse) httpClient.execute(httpPost);
resp = EntityUtils.toString(response.getEntity(), encoding);
} catch (Exception e) {
// log
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
// log
e.printStackTrace();
}
}
}
return resp;
}
/**
* 发送post请求
* @param url 请求地址
* @param params 请求参数
* @return
*/
public static String sendPost(String url, Map params) {
Charset encoding = Charset.forName("utf8");
return sendPost(defaultClient, url, params, encoding);
}
}
以上是工具类,调用如下:
if(getPara("NECaptchaValidate")==null||getPara("NECaptchaValidate").equals("")){
setAttr("state", new State("/","滑动验证失败,请重新尝试!","5","102"));
renderJsp("/new_nei/funm.jsp");
return;
}
WYyzm wy=new WYyzm((String.valueOf(getPara("NECaptchaValidate"))),"");
String validate =getPara("NECaptchaValidate");
NECaptchaVerifier verifier = new NECaptchaVerifier(wy.getCaptchaId(), new NESecretPair(wy.getSecretId(), wy.getKey()));
boolean isValid = verifier.verify(validate, ""); // 发起二次校验
System.out.println("validate = " + validate + ", isValid = " + isValid);
if (isValid) {
System.out.println("滑动验证二次校验成功!");
} else {
setAttr("state", new State("/","滑动验证失败,请重新尝试!","5","102"));
renderJsp("/new_nei/funm.jsp");
return;
}