feat: 滑块验证码增加服务器端验证

This commit is contained in:
Argo Zhang 2019-08-27 12:06:06 +08:00
parent 1b7fec25e4
commit 17914936dc
4 changed files with 139 additions and 84 deletions

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.Controllers.Api
{
/// <summary>
/// Gitee 网站信息接口类
/// </summary>
[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class CaptchaController : ControllerBase
{
/// <summary>
/// 服务器端滑块验证方法
/// </summary>
/// <returns></returns>
[HttpPost]
public bool Post([FromBody]List<int> datas)
{
var sum = datas.Sum();
var avg = sum * 1.0 / datas.Count;
var stddev = datas.Select(v => Math.Pow(v - avg, 2)).Sum() / datas.Count;
return stddev != 0;
}
}
}

View File

@ -15,7 +15,8 @@
that.sliderCaptcha('reset'); that.sliderCaptcha('reset');
$('.userinfo .dropdown-menu a:first')[0].click(); $('.userinfo .dropdown-menu a:first')[0].click();
}, 1000); }, 1000);
} },
remoteUrl: $.formatUrl('api/Captcha')
}); });
$('#btnCaptcha').on('click', function () { $('#btnCaptcha').on('click', function () {

View File

@ -24,7 +24,24 @@
maxLoadCount: 3, maxLoadCount: 3,
localImages: function () { localImages: function () {
return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg'; return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg';
} },
verify: function (arr, url) {
var ret = false;
$.ajax({
url: url,
data: JSON.stringify(arr),
async: false,
cache: false,
type: 'POST',
contentType: 'application/json',
dataType: 'json',
success: function (result) {
ret = result;
}
});
return ret;
},
remoteUrl: null
}; };
function Plugin(option) { function Plugin(option) {
@ -273,16 +290,23 @@
}; };
_proto.verify = function () { _proto.verify = function () {
var sum = function (x, y) { return x + y; };
var square = function (x) { return x * x; };
var arr = this.trail; // 拖动时y轴的移动距离 var arr = this.trail; // 拖动时y轴的移动距离
var average = arr.reduce(sum) / arr.length;
var deviations = arr.map(function (x) { return x - average; });
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
var left = parseInt(this.block.style.left); var left = parseInt(this.block.style.left);
var verified = false;
if (this.options.remoteUrl !== null) {
verified = this.options.verify(arr, this.options.remoteUrl);
}
else {
var sum = function (x, y) { return x + y; };
var square = function (x) { return x * x; };
var average = arr.reduce(sum) / arr.length;
var deviations = arr.map(function (x) { return x - average; });
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
verified = stddev !== 0;
}
return { return {
spliced: Math.abs(left - this.x) < this.options.offset, spliced: Math.abs(left - this.x) < this.options.offset,
verified: stddev !== 0 // 简单验证下拖动轨迹为零时表示Y轴上下没有波动可能非人为操作 verified: verified
}; };
}; };

View File

@ -1,131 +1,131 @@
body { body {
overflow-x: hidden; overflow-x: hidden;
} }
.block { .block {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
} }
.sliderContainer { .sliderContainer {
position: relative; position: relative;
text-align: center; text-align: center;
line-height: 40px; line-height: 40px;
background: #f7f9fa; background: #f7f9fa;
color: #45494c; color: #45494c;
border-radius: 2px; border-radius: 2px;
} }
.sliderbg { .sliderbg {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
top: 0; top: 0;
background-color: #f7f9fa; background-color: #f7f9fa;
height: 40px; height: 40px;
border-radius: 2px; border-radius: 2px;
border: 1px solid #e6e8eb; border: 1px solid #e6e8eb;
} }
.sliderContainer_active .slider { .sliderContainer_active .slider {
top: -1px; top: -1px;
border: 1px solid #1991FA; border: 1px solid #1991FA;
} }
.sliderContainer_active .sliderMask { .sliderContainer_active .sliderMask {
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
} }
.sliderContainer_success .slider { .sliderContainer_success .slider {
top: -1px; top: -1px;
border: 1px solid #52CCBA; border: 1px solid #52CCBA;
background-color: #52CCBA !important; background-color: #52CCBA !important;
} }
.sliderContainer_success .sliderMask { .sliderContainer_success .sliderMask {
border: 1px solid #52CCBA; border: 1px solid #52CCBA;
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
background-color: #D2F4EF; background-color: #D2F4EF;
} }
.sliderContainer_success .sliderIcon:before { .sliderContainer_success .sliderIcon:before {
content: "\f00c"; content: "\f00c";
} }
.sliderContainer_fail .slider { .sliderContainer_fail .slider {
top: -1px; top: -1px;
border: 1px solid #f57a7a; border: 1px solid #f57a7a;
background-color: #f57a7a !important; background-color: #f57a7a !important;
} }
.sliderContainer_fail .sliderMask { .sliderContainer_fail .sliderMask {
border: 1px solid #f57a7a; border: 1px solid #f57a7a;
background-color: #fce1e1; background-color: #fce1e1;
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
} }
.sliderContainer_fail .sliderIcon:before { .sliderContainer_fail .sliderIcon:before {
content: "\f00d"; content: "\f00d";
} }
.sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText { .sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText {
display: none; display: none;
} }
.sliderMask { .sliderMask {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
height: 40px; height: 40px;
border: 0 solid #1991FA; border: 0 solid #1991FA;
background: #D1E9FE; background: #D1E9FE;
border-radius: 2px; border-radius: 2px;
} }
.slider { .slider {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 40px; width: 40px;
height: 40px; height: 40px;
background: #fff; background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
cursor: pointer; cursor: pointer;
transition: background .2s linear; transition: background .2s linear;
border-radius: 2px; border-radius: 2px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.slider:hover { .slider:hover {
background: #1991FA; background: #1991FA;
} }
.slider:hover .sliderIcon { .slider:hover .sliderIcon {
background-position: 0 -13px; background-position: 0 -13px;
} }
.sliderText { .sliderText {
position: relative; position: relative;
} }
.sliderIcon { .sliderIcon {
} }
.refreshIcon { .refreshIcon {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
cursor: pointer; cursor: pointer;
margin: 6px; margin: 6px;
color: rgba(0,0,0,.25); color: rgba(0,0,0,.25);
font-size: 1rem; font-size: 1rem;
z-index: 5; z-index: 5;
transition: color .3s linear; transition: color .3s linear;
} }
.refreshIcon:hover { .refreshIcon:hover {
color: #6c757d; color: #6c757d;
} }