Google reCAPTCHA 介绍
- Google reCAPTCHA 是采用用户行为验证类型的验证码,目前来说几乎不能被打码平台自动打码(这里指 Google reCAPTCHA 并不是指所有用户行为验证码,据说Google reCAPTCHA还是用了js vmp虚拟机技术),也只能人工打码。
- Google 验证码是 Google 提供的一项免费的验证码服务,接入非常简单,推荐用它来替换传统的图片验证码。
V2版效果
Google reCAPTCHA必要准备
- 创建Key地址:https://www.google.com/recaptcha/admin/create
- 需要准备一个谷歌账号,在创建秘钥时需要将当前秘钥与一个谷歌账号绑定。
- 创建秘钥的地址必须科学上网,否则无法访问。
ASP.NET Core 接入
-
安装 reCAPTCHA 组件
dotnet add package Unicorn.reCAPTCHA.AspNetCore
-
appsettings.json 添加配置
"RecaptchaSettings": { "SiteKey": "6LfiM0glAAAAADfxVfNSlYXiSJ6W3RoZ79Qi6vKj", //网站密钥,公钥,前端用 "SecretKey": "6LfiM0glAAAAAKfSVy20CSVgOhNcKRhFC5G1jbx6", //通信密钥,私钥,后端用 "Version": "v2", "Domain": "www.recaptcha.net" //Domain 指使用的 Google reCAPTCHA 服务的域名,可以是www.recaptcha.net 或者 www.google.com,使用前者可以在国内正常使用,不受GFW影响。 }
- 在 Program.cs 方法里配置
var configuration = builder.Configuration.GetSection("RecaptchaSettings"); builder.Services.AddGoogleRecaptcha(configuration);
- 后台代码 (/Controllers/AccountController.cs)
public class AccountController : Controller { private readonly IRecaptchaService _recaptcha; private readonly IOptions<RecaptchaSettings> _options; public AccountController(IRecaptchaService recaptcha, IOptions<RecaptchaSettings> options) { _recaptcha = recaptcha; _options = options; } #region Login_V2 /// <summary> /// https://www.cnblogs.com/echolun/p/12436226.html /// </summary> /// <returns></returns> public IActionResult Login_V2() { ViewBag.SiteKey = _options.Value.SiteKey;//公钥 return View(); } [HttpPost] public async Task<IActionResult> Login_V2(AccountViewModel model) { if (ModelState.IsValid) { var recaptchaReault = await _recaptcha.Validate(model.GoogleToken); if (!recaptchaReault.Success) { return Json(new { code = 0, msg = "人机验证失败,请稍后重试!" }); } return Json(new { code = 200, msg = "人机验证成功", data = model }); } else { return Json(new { code = 0, msg = "参数异常" }); } } #endregion }
public class AccountViewModel { [Required(ErrorMessage = "{0}不能为空")] public string Username { get; set; } [Required(ErrorMessage = "{0}不能为空")] public string Password { get; set; } [Required(ErrorMessage = "{0}不能为空")] public string GoogleToken { get; set; } }
- 前端代码 (/Views/Account/Login_V2.cshtml)
@{ ViewData["Title"] = "Login_V2"; Layout = null; } <link rel="stylesheet" href="http://layui.tool90.com/res/layui/dist/css/layui.css" /> <fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;"> <legend>登录演示</legend> </fieldset> <form class="layui-form"> <div class="layui-form-item"> <label class="layui-form-label">用户名</label> <div class="layui-input-block"> <input type="text" name="username" lay-verify="required" autocomplete="off" class="layui-input" value="admin"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密码</label> <div class="layui-input-block"> <input type="text" name="password" lay-verify="required" placeholder="请输入" autocomplete="off" class="layui-input" value=""> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">验证</label> <div class="layui-input-inline"> <div id="recaptcha_bar"></div> <button type="button" class="layui-btn layui-btn-sm" onclick="refreshGrecaptcha()">刷新验证</button> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">提示</label> <div class="layui-form-mid"> <div id="tips">--</div> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button type="button" class="layui-btn" lay-submit="" lay-filter="btnLogin">登录</button> </div> </div> </form> <script src="/lib/jquery/dist/jquery.js"></script> <script src="http://layui.tool90.com/res/layui/dist/layui.js"></script> <script src="https://www.recaptcha.net/recaptcha/api.js?onload=onloadWidget&hl=zh-CN" async defer></script> <script> layui.use(['form'], function () { var form = layui.form , layer = layui.layer; //监听提交 form.on('submit(btnLogin)', function (data) { var responseToken = grecaptcha.getResponse(widgetId); if (responseToken.length == 0) { $("#tips").html("请进行人机身份验证").css("color", "red"); return false; } //console.log(JSON.stringify(data.field)); var formData = data.field; formData.GoogleToken = responseToken; $.post("/Account/Login_V2", formData).done(function (result) { if (result.code == 200) { $("#tips").html(result.msg).css("color", "green"); } else { refreshGrecaptcha();//重新获得一个Token $("#tips").html(result.msg).css("color", "red"); } }) return false; }); }); </script> <script type="text/javascript"> //验证成功回调 var callback = function (args) { console.log(args) console.log('验证成功'); }; //验证过期回调 var expiredCallback = function (args) { console.log(args) console.log('验证过期'); }; //验证错误回调 var errorCallback = function (args) { console.log(args) console.log('验证失败'); }; var widgetId; //加载所有依赖项后--初始化组件 var onloadWidget = function () { // 得到组件id widgetId = grecaptcha.render('recaptcha_bar', { 'sitekey': '@(ViewBag.SiteKey)', //公钥 'theme': 'light',//主题颜色,有light与dark两个值可选 'size': 'normal',//尺寸规则,有normal与compact两个值可选 'callback': callback, //验证成功回调 'expired-callback': expiredCallback, //验证过期回调 'error-callback': errorCallback//验证错误回调 }); }; //刷新 function refreshGrecaptcha() { grecaptcha.reset(widgetId); } </script>
使用前需注意:
1.reCaptcha官网网站为:https://developers.google.com/recaptcha/(需要翻墙)
2.在国内使用的话,需要将demo中所有的www.google.com替换成www.recaptcha.net不然无法使用reCAPTCHA