From 17914936dcc19794629f3ca41ebdec031357c707 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 27 Aug 2019 12:06:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=BB=91=E5=9D=97=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E5=A2=9E=E5=8A=A0=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=AB=AF?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Api/CaptchaController.cs | 30 ++++ Bootstrap.Client/wwwroot/js/index.js | 3 +- .../lib/captcha/longbow.slidercaptcha.js | 38 ++++- .../wwwroot/lib/captcha/slidercaptcha.css | 152 +++++++++--------- 4 files changed, 139 insertions(+), 84 deletions(-) create mode 100644 Bootstrap.Client/Controllers/Api/CaptchaController.cs diff --git a/Bootstrap.Client/Controllers/Api/CaptchaController.cs b/Bootstrap.Client/Controllers/Api/CaptchaController.cs new file mode 100644 index 00000000..8695b0aa --- /dev/null +++ b/Bootstrap.Client/Controllers/Api/CaptchaController.cs @@ -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 +{ + /// + /// Gitee 网站信息接口类 + /// + [Route("api/[controller]")] + [ApiController] + [AllowAnonymous] + public class CaptchaController : ControllerBase + { + /// + /// 服务器端滑块验证方法 + /// + /// + [HttpPost] + public bool Post([FromBody]List 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; + } + } +} diff --git a/Bootstrap.Client/wwwroot/js/index.js b/Bootstrap.Client/wwwroot/js/index.js index 57082259..eb770007 100644 --- a/Bootstrap.Client/wwwroot/js/index.js +++ b/Bootstrap.Client/wwwroot/js/index.js @@ -15,7 +15,8 @@ that.sliderCaptcha('reset'); $('.userinfo .dropdown-menu a:first')[0].click(); }, 1000); - } + }, + remoteUrl: $.formatUrl('api/Captcha') }); $('#btnCaptcha').on('click', function () { diff --git a/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js index 8d5d74bf..85774459 100644 --- a/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js +++ b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js @@ -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 }; }; diff --git a/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css b/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css index cf3e91be..c2c8f102 100644 --- a/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css +++ b/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css @@ -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; + }