登录前的人机验证VAPTCHA
程序员文章站
2022-03-21 11:37:25
验证流程1、创建验证单元,获取VID和Key 。点击创建。2、将https://v.vaptcha.com/v3.js引入到你的页面。3、将 VAPTCHA 初始化到你需要的位置4、用户验证通过得到token,与表单数据一同提交到服务端。5、服务端得到token后,向 VAPTCHA 服务器验证token的有效性,验证通过说明此次请求有效.......
具体查看官方文档:https://www.vaptcha.com/document/install.html
验证流程
1、创建验证单元,获取VID和Key ,需要去官方系统创建VID和Key
2、将https://v.vaptcha.com/v3.js引入到你的页面。
3、将 VAPTCHA 初始化到你需要的位置
4、用户验证通过得到token,与表单数据一同提交到服务端。
5、服务端得到token后,向 VAPTCHA 服务器验证token的有效性,验证通过说明此次请求有效.
前端验证
1、引入前端 sdk:
<script src="https://v.vaptcha.com/v3.js"></script>
2、引入验证框样式
<style>
.vaptcha-init-main {
display: table;
width: 100%;
height: 100%;
background-color: #eeeeee;
}
.vaptcha-init-loading {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.vaptcha-init-loading > a {
display: inline-block;
width: 18px;
height: 18px;
border: none;
}
.vaptcha-init-loading > a img {
vertical-align: middle;
}
.vaptcha-init-loading .vaptcha-text {
font-family: sans-serif;
font-size: 12px;
color: #cccccc;
vertical-align: middle;
}
vaptcha({
vid: "*****", // 验证单元id
type: "invisible", // 显示类型 隐藏式
scene: 0, // 场景值
offline_server: "localhost" //离线模式服务端地址,若尚未配置离线模式,请填写任意地址即可。
}).then(function (vaptchaObj) {
vaptchaVerifyObj = vaptchaObj; //将VAPTCHA验证实例保存到局部变量中
vaptchaObj.listen("pass", function () {
let token = vaptchaObj.getToken();
let username= $('#username').val().trim();
let password = $('#pwd').val().trim();
login(userame,password,token);
});
});
function login(username,password,token){
var param ={"username":username,"password":password,"token":token}
$.post("login/login",param,function(data){
if(data.code == 'vaptcha'){
//执行人机验证
vaptchaVerifyObj.validate();
}else{
if(data.code == 'vaptchaFail'){
layer.msg('人机验证失败,请重试', {icon: 5,offset: '40%'});
}else{
layer.msg('登录失败!', {icon: 5,offset: '40%'});
}
}
//人机验证时当登录失败时重置
if(data.code != 'success' || data.code!= 'vaptcha'){
vaptchaVerifyObj.reset();
}
}
}
后端验证
@ResponseBody
@RequestMapping("/login")
public void login(HttpServletRequest request,HttpServletResponse response) throws Exception {
HashMap<String,Object> result = new HashMap<String, Object>();
String username = WebUtil.decode(request.getParameter("username"));
String password = request.getParameter("password");
String token = request.getParameter("token");
if(StringUtils.isBlank(username) || StringUtils.isBlank(password)){
result .put("code", "failed");
return result;
}
//人机验证
String ip = getIpAddress(request);
HashMap<String,Object> vaptchaVerifyResult = vaptchaVerify(token,ip);
if(!"success".equals(vaptchaVerifyResult.get("code"))){
result .put("code", vaptchaVerifyResult.get("code"));
return result ;
}
}
获取客户端IP地址
public String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
人机验证
public HashMap<String,Object> vaptchaVerify(String token,String ip) {
HashMap<String,Object> resultMap = new HashMap<String, Object>();
//人机验证token为空
if(StringUtils.isBlank(token)){
resultMap.put("code", "vaptcha");
return resultMap;
}
//对获取到的人机验证token进行正确性校验,防止机器人请求
if(StringUtils.isNotBlank(token)){
HashMap<String,String> map = new HashMap<String, String>();
map.put("id", "*****");
map.put("secretkey", "*****");
map.put("scene", "0");
map.put("token", token);
map.put("ip", ip);
try {
String vaptchaInfo = getInfoPost(map,"http://0.vaptcha.com/verify");//请求api接口验证token是否正确
//将请求结果字符串转json
JSONObject vaptchaInfoJson = JSONObject.fromObject(vaptchaInfo);
Integer success = (Integer)vaptchaInfoJson.get("success");//验证结果,1为通过,0为失败
if(success != 1){
resultMap.put("code", "vaptchaFail");
return resultMap;
}
} catch (Exception e) {
e.printStackTrace();
resultMap.put("code", "vaptchaFail");
return resultMap;
}
}
resultMap.put("code", "success");
return resultMap;
}
调用接口获取数据
public String getInfoPost(HashMap<String, String> map, String URL) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(URL);
if (map != null) {
for (String key : map.keySet()) {
builder.addParameter(key, map.get(key).toString());
}
}
URI uri = builder.build();
// 创建http POST请求
HttpPost httpPost = new HttpPost(uri);
// 执行请求
response = httpclient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(),"UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
本案例仅为初步使用vaptcha免费版,用于产品时,请根据官方手册配置离线模式,以及购买vaptcha高级版。
本文地址:https://blog.csdn.net/fffvdgjvbsfkb123456/article/details/110946500
推荐阅读
-
spring aop action中验证用户登录状态的实例代码
-
没有sa密码无法集成windows身份验证登录的解决方法
-
详解Spring Security的HttpBasic登录验证模式
-
详解JS实现系统登录页的登录和验证
-
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
-
PHP curl模拟登录带验证码的网站
-
IDEA+MySQL实现登录注册的注册验证时出现 Cannot resolve query parameter '2'
-
vuex + axios 做登录验证 并且保存登录状态的实例
-
Unity登录注册时限制发送验证码次数功能的解决方法
-
SpringCloud-使用路由网关的服务过滤功能-拦截登录前是否有token为例