feat: 滑块验证码增加服务器端验证
This commit is contained in:
parent
1b7fec25e4
commit
17914936dc
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,8 @@
|
|||
that.sliderCaptcha('reset');
|
||||
$('.userinfo .dropdown-menu a:first')[0].click();
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
remoteUrl: $.formatUrl('api/Captcha')
|
||||
});
|
||||
|
||||
$('#btnCaptcha').on('click', function () {
|
||||
|
|
|
@ -24,7 +24,24 @@
|
|||
maxLoadCount: 3,
|
||||
localImages: function () {
|
||||
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) {
|
||||
|
@ -273,16 +290,23 @@
|
|||
};
|
||||
|
||||
_proto.verify = function () {
|
||||
var sum = function (x, y) { return x + y; };
|
||||
var square = function (x) { return x * x; };
|
||||
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 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 {
|
||||
spliced: Math.abs(left - this.x) < this.options.offset,
|
||||
verified: stddev !== 0 // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
|
||||
verified: verified
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,131 +1,131 @@
|
|||
body {
|
||||
overflow-x: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.block {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.sliderContainer {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
background: #f7f9fa;
|
||||
color: #45494c;
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
background: #f7f9fa;
|
||||
color: #45494c;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.sliderbg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background-color: #f7f9fa;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #e6e8eb;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background-color: #f7f9fa;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #e6e8eb;
|
||||
}
|
||||
|
||||
.sliderContainer_active .slider {
|
||||
top: -1px;
|
||||
border: 1px solid #1991FA;
|
||||
top: -1px;
|
||||
border: 1px solid #1991FA;
|
||||
}
|
||||
|
||||
.sliderContainer_active .sliderMask {
|
||||
border-width: 1px 0 1px 1px;
|
||||
border-width: 1px 0 1px 1px;
|
||||
}
|
||||
|
||||
.sliderContainer_success .slider {
|
||||
top: -1px;
|
||||
border: 1px solid #52CCBA;
|
||||
background-color: #52CCBA !important;
|
||||
top: -1px;
|
||||
border: 1px solid #52CCBA;
|
||||
background-color: #52CCBA !important;
|
||||
}
|
||||
|
||||
.sliderContainer_success .sliderMask {
|
||||
border: 1px solid #52CCBA;
|
||||
border-width: 1px 0 1px 1px;
|
||||
background-color: #D2F4EF;
|
||||
border: 1px solid #52CCBA;
|
||||
border-width: 1px 0 1px 1px;
|
||||
background-color: #D2F4EF;
|
||||
}
|
||||
|
||||
.sliderContainer_success .sliderIcon:before {
|
||||
content: "\f00c";
|
||||
content: "\f00c";
|
||||
}
|
||||
|
||||
.sliderContainer_fail .slider {
|
||||
top: -1px;
|
||||
border: 1px solid #f57a7a;
|
||||
background-color: #f57a7a !important;
|
||||
top: -1px;
|
||||
border: 1px solid #f57a7a;
|
||||
background-color: #f57a7a !important;
|
||||
}
|
||||
|
||||
.sliderContainer_fail .sliderMask {
|
||||
border: 1px solid #f57a7a;
|
||||
background-color: #fce1e1;
|
||||
border-width: 1px 0 1px 1px;
|
||||
border: 1px solid #f57a7a;
|
||||
background-color: #fce1e1;
|
||||
border-width: 1px 0 1px 1px;
|
||||
}
|
||||
|
||||
.sliderContainer_fail .sliderIcon:before {
|
||||
content: "\f00d";
|
||||
content: "\f00d";
|
||||
}
|
||||
|
||||
.sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sliderMask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 40px;
|
||||
border: 0 solid #1991FA;
|
||||
background: #D1E9FE;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 40px;
|
||||
border: 0 solid #1991FA;
|
||||
background: #D1E9FE;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
|
||||
cursor: pointer;
|
||||
transition: background .2s linear;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
|
||||
cursor: pointer;
|
||||
transition: background .2s linear;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
background: #1991FA;
|
||||
}
|
||||
.slider:hover {
|
||||
background: #1991FA;
|
||||
}
|
||||
|
||||
.slider:hover .sliderIcon {
|
||||
background-position: 0 -13px;
|
||||
}
|
||||
.slider:hover .sliderIcon {
|
||||
background-position: 0 -13px;
|
||||
}
|
||||
|
||||
.sliderText {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sliderIcon {
|
||||
|
||||
}
|
||||
|
||||
.refreshIcon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
margin: 6px;
|
||||
color: rgba(0,0,0,.25);
|
||||
font-size: 1rem;
|
||||
z-index: 5;
|
||||
transition: color .3s linear;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
margin: 6px;
|
||||
color: rgba(0,0,0,.25);
|
||||
font-size: 1rem;
|
||||
z-index: 5;
|
||||
transition: color .3s linear;
|
||||
}
|
||||
|
||||
.refreshIcon:hover {
|
||||
color: #6c757d;
|
||||
}
|
||||
.refreshIcon:hover {
|
||||
color: #6c757d;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue