您的位置:首页 > 其它

滑动拼图解锁

2017-01-18 21:00 183 查看
突发奇想把六位验证码登录换成滑动,后又想要加拼图解锁,苦于js技术与css技术实在是差,于是在网上找到了这个

网易云盾:点击打开链接

注册后登陆,找到下面我的产品,创建一个免费的验证码产品



然后点击创建产品操作栏的查看详情







jsp页面代码如下:

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<title>易盾验证码-DEMO</title>
<!-- 演示用js/css,非组件依赖 -->
<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<link href='//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.css' rel='stylesheet'>
</head>
<body>
<form style="max-width: 320px; margin: 120px auto;" action="/login" method="post">
<h2 class="form-signin-heading">易盾验证码</h2>
<input type="text" class="form-control" name="username" placeholder="账号" />
<input type="password" class="form-control" name="password" placeholder="密码" />
<div style="margin: 10px auto;" id="captcha_div"></div> <!-- 验证码容器元素定义 -->
<button class="btn btn-lg btn-primary btn-block" type="submit"
disabled="disabled" id="submit-btn">登录</button>
</form>
<script src="//c.dun.163yun.com/js/c.js"></script><!-- 验证码组件js -->
<script> // 验证码组件初始化
var opts = {
"element": "captcha_div", // 可以是验证码容器id,也可以是HTMLElement
"captchaId": "ce904ccc5805479db5ae71c5febafcfb", // 这里填入申请到的验证码id
"width": 320, // 验证码组件显示宽度
"verifyCallback": function(ret){ // 用户只要有拖动/点击,就会触发这个回调
if(ret['value']){ // true:验证通过 false:验证失败
// 通过 ret["validate"] 可以获得二次校验数据
$("#submit-btn").removeAttr("disabled"); // 用户完成拖动之后再启用提交按钮
}
}
}
new NECaptcha(opts);
</script>
</body>
</html>


值得注意的是引用顺序:先引用验证码组件js,然后初始化,验证码组件初始化要在验证码容器的下面



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<String, String> params=new HashMap<String, String>();

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<String, String> params = new HashMap<String, String>();
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<String, String> 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<String, String> params, Charset encoding) {
String resp = "";
HttpPost httpPost = new HttpPost(url);
if (params != null && params.size() > 0) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
Iterator<Map.Entry<String, String>> itr = params.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, String> 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<String, String> 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: