滑动拼图解锁
2017-01-18 21:00
183 查看
突发奇想把六位验证码登录换成滑动,后又想要加拼图解锁,苦于js技术与css技术实在是差,于是在网上找到了这个
网易云盾:点击打开链接
注册后登陆,找到下面我的产品,创建一个免费的验证码产品
然后点击创建产品操作栏的查看详情
jsp页面代码如下:
值得注意的是引用顺序:先引用验证码组件js,然后初始化,验证码组件初始化要在验证码容器的下面
以上是工具类,调用如下:
网易云盾:点击打开链接
注册后登陆,找到下面我的产品,创建一个免费的验证码产品
然后点击创建产品操作栏的查看详情
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; }
相关文章推荐
- Axure实战:滑动拼图解锁教程
- iPhone新颖华丽解锁界面:滑动折叠
- 手机滑动图案解锁
- 【叶节点记忆式/深搜式DFS_路径搜索问题】滑动解锁
- Android自定义绘制:Shader - 模仿iOS滑动解锁
- python九宫格滑动解锁
- android滑动解锁的震动效果
- javascript实现滑动解锁功能
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- 蓝桥杯模拟赛:滑动解锁
- CAGradientLayer(颜色渐变) -- 实现iphone手机屏幕“滑动来解锁”动画效果
- CAGradientLayer实现"滑动来解锁"动画效果
- 仿ios全屏滑动解锁,带阴影效果
- iOS实现手势滑动解锁功能简析
- Java实现九宫格滑动解锁
- Swift: 打造滑动解锁文字动画
- 授予解锁本该遭拒的十大科技专利:苹果滑动解锁上榜
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- 报数游戏,滑动解锁,蓝桥
- Android自定义滑动解锁控件使用详解