壹 ❀ 引
在日常页面交互中,验证码使用是极为频繁的,登录注册验证,非机器人操作验证等等,它遍布于每一个网站。说到验证码实现,Goole Recaptcha是一个非常不错的选择,那么希望通过本文的使用介绍,能让你对于验证码的实现多一种可能性,让我们开始。
贰 ❀ 使用准备与一些基本概念
贰 ❀ 壹 必要准备
- 需要准备一个谷歌账号,在创建秘钥时需要将当前秘钥与一个谷歌账号绑定。
- 有特殊上网的途径,创建秘钥的地址必须特殊上网,否则无法访问。
- 具备本地服务器,测试时需要使用,毕竟总不能直接拿项目直接上手,如果你不知道怎么搭建服务器,这里推荐live server,npm下载启动就可以了,使用非常简单,这里就不细说了。
贰 ❀ 贰 一些基本概念
Google Rechaptcha版本说明:
reCAPTCHA v3:v3版本可以不通过任何用户交互进行验证,并返回一个分数,开发者可以根据分数进行验证提示,一般用于限制爬虫等。
reCAPTCHA v2 复选框版本:用户可以通过点击“我不是机器人”的复选框,从而触发图片选择以及后续的验证操作,类似图。
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184701972-1222786791.png)
reCAPTCHA v2 隐式验证版本:与复选框模式职责相同,区别在于用户使用时看不到复选框,取而代之的是通过点击按钮触发后续验证,比如博客园登录,用户在输入完账号密码后点击登录按钮,这时会弹出图片验证,如果通过了验证才会发起来登录请求。
reCAPTCHA v2 Android版本:安卓使用的验证。
V2版本分为复选框、隐式验证、安卓三个版本,本文主要围绕前两个版本展开介绍,注意,使用不同版本都得创建对应的秘钥,在开发中如果存在版本替换,一定记得对应替换秘钥。
Google Rechaptcha秘钥说明:
秘钥分为客户端秘钥与服务端秘钥,也就是俗称的公钥与私钥,这是一对,如下图是我创建的一对秘钥:
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184735652-1430690885.png)
知道了这些,我们现在来创建属于自己的秘钥。
贰 ❀ 叁 创建秘钥
点击创建秘钥,虽然此链接需要科学访问,但是界面却是中文....非常友好,说说创建步骤:
- 输入标签,也就是取个名字,万一版本创建多了好通过标签区分,这里我就叫
demo
。 - 选择recaptcha版本,这里我先选择
进行人机身份验证复选框
版本。 - 输入域名,这对秘钥用在哪,本地服务器启动一般都是localhost,这里输入
localhost
。 - 所有者,当前秘钥创建与哪个邮箱关联,一般登录谷歌默认关联自己的谷歌账号。
- 接受recaptcha服务条款,向所有者发出提醒,默认勾选不用管。
- 点击提交,就可以成功创建出一对秘钥了。
秘钥有了,现在我们来使用它,开始客户端(前端)集成。
叁 ❀ 客户端(前端)集成说明
叁 ❀ 壹 复选框模式的两种加载方法
v2复选框版本初始化分为自动加载与显示加载两种形式,说到底就是提供了两种初始化模式。自动加载就是将初始化配置直接加在dom上,显示加载则是利用谷歌提供的API启动,没太大区别,我们先说自动加载怎么玩。
不管是自动加载还是显示加载,第一步都是得引用google recaptcha js资源文件,如下:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
注意,如果我们项目是国内访问,需要将www.google.com
替换成www.recaptcha.net
即可。
<script src="https://`www.recaptcha.net/recaptcha/api.js" async defer></script>
第二步就是配置dom,最简单的配置如下:
<div class="g-recaptcha" data-sitekey="客户端秘钥"></div>
注意,这个dom标签必须添加g-recaptcha
的class名,data-sitekey
填写你创建的秘钥,刷新页面,就可以看到验证码已经创建好了:
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184809404-898423071.gif)
是不是很简单?当然有的人不喜欢把一堆属性加在dom上,更希望通过js API来使用,没关系,我们来看看显示加载是怎么玩的。
第一步还是引入js资源文件,与上面一样,这个时候我们创建一个验证码容器,其实就是一个装载验证码组件的盒子,如下:
<div id="robot"></div>
标签没硬性要求,但一定要加一个id,在js中我们会使用到这个id,接下来是在js中做初始化工作:
grecaptcha.render('robot', {
'sitekey': '6Lfjdd8UAAAAAKzWxI0k59BW5Tcf1C76XPKir1sr', //公钥
'theme': 'light', //主题颜色,有light与dark两个值可选
'size': 'compact',//尺寸规则,有normal与compact两个值可选
'callback': callback, //验证成功回调
'expired-callback': expiredCallback, //验证过期回调
'error-callback': errorCallback //验证错误回调
});
刷新页面,你会发现验证码成功展示出来了。聪明的同学已经发现了,grecaptcha.render()
就是验证码组件初始化方法,它接受两个参数,前者为组件容器id,也就是我们在div上添加的robot
;第二个参数是一个对象,也就是组件相关配置。
有同学就纳闷了,为啥通过API调用显示加载可以加这么多属性,dom形式自动加载能不能加这些配置?当然能,以sitekey
为例,在作为标签属性时你得写作data-sitekey
,同理,theme
用在标签上时也得加上data-
前缀,其它属性配置全部如此。
在解释这些属性前,我先附上一个完整的例子,大家直接复制替换下公钥,这样下面的解释可以同步修改理解:
<-- HTML部分 -->
<div id="robot"></div>
<button onclick="getResponseFromRecaptcha()">验证是否通过</button>
<-- 记得引用js -->
<script src="https://www.recaptcha.net/recaptcha/api.js onload=onloadCallback&render=explicit&hl=en" async defer>
//js部分
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 onloadCallback = function () {
// 得到组件id
widgetId = grecaptcha.render('robot', {
'sitekey': '6LcYMd4UAAAAABb4jumQHY9ftHhZ3R0N2QxtACCp',
'theme': 'light',
'size': 'compact',
'callback': callback,
'expired-callback': expiredCallback,
'error-callback': errorCallback
});
};
function getResponseFromRecaptcha() {
var responseToken = grecaptcha.getResponse(widgetId);
if (responseToken.length == 0) {
alert("验证失败");
} else {
alert("验证通过");
}
};
叁 ❀ 贰 配置参数说明
sitekey(data-sitekey):客户端秘钥,也就是我们创建的秘钥,这是必填项。
theme(data-theme):验证码组件主题色,默认light,还有一个dark可选,颜色对比如下:
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184843798-1486957002.png)
size(data-size):验证码尺寸规则,默认normal也就是长方形,可选值compact正方形,如下:
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184912155-1123497495.png)
callback(data-callback):验证成功回调,比如用户点击了我不是机器人复选框,弹出了图片,用户在选择完图片点击右下角的验证,如果验证成功便会触发此回调,比如上方例子验证成功后输出了验证成功
以及一大段乱码字符,这段字符官方称为 response token
,后端会使用到这个token,我们在后面具体说。
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307184937213-75955859.png)
expired-callback(data-expired-callback):过期回调,如果用户第一次验证成功后页面放置一段时间,当前验证就会过期,一旦过期谷歌会自动调用过期回调,如下:
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307185001677-1125859082.png)
error-callback(data-error-callback):错误回调,验证过程中如果出现错误便会执行这个回调。
叁 ❀ 叁 API说明
我们已经通过上面的例子了解了初始化组件的API,谷歌验证码一共也就提供了三个API,如下:
grecaptcha.render(container,parameters)
初始化API,上文已经解释了两个参数的含义,在调用此方法后会返回一个验证码组件id,毕竟一个页面可能会有多处使用验证码,该id用于区分不同验证码组件。
grecaptcha.reset(opt_widget_id)
重新加载组件API,接受一个参数,也就是render方法返回的验证码组件id,如果不填,则默认初始化页面中第一个验证码。
grecaptcha.getResponse(opt_widget_id)
获取组件验证状态的api,同样接受一个验证码id作为参数,用于获取指定id的验证码验证状态,如果不填,则默认获取第一个验证码状态。获取的结果有两种情况,如果成功,拿到的也就是前面我们说到的response token,如果失败则拿到的是空字符串。
在上文例子我们同样提供了这个方法,大家可以在验证成功和过期两种情况下分别点击验证是否通过
的按钮查看不同结果。
有同学一定会纳闷getResponse
方法有啥用,说个很简单的例子,用户登录输完了账号密码,只要点击提交按钮,我们就可以通过此方法判断用户有没有提前通过验证,如果通过了再请求登录接口。
叁 ❀ 肆 url参数说明
细心的同学一定发现上方例子提供的js 引用后缀有点不同,其实js引用地址也接受三个参数,也不是很复杂,我们来解释下分别表示啥意思:
<script src="https://www.recaptcha.net/recaptcha/api.js onload=onloadCallback&render=explicit&hl=en" async defer
首先,onload,render与hl都不是必填参数,填不填看你自己。
onload:加载所有依赖项后要执行的回调函数的名称,参考上方例子,等资源加载完毕,我们才执行onloadCallback
方法初始化组件。
render:是否显式加载组件,默认值为onload
,表示自动加载,也就是默认找到第一个class为g-recaptcha
的标签来加载组件。例子中我们设置的值为explicit
,意思是不启用自动加载,而是根据我们提供的DOM id进行加载。
hl:语言种类,你希望组件用哪种语言展示,详细的语言表参考。如果不设置,则自动检测浏览器语言并作为标准。
OK,到这里,关于复选框模式的使用就全部说完了!!!!!
我们来说说V2隐式验证版本咋玩,由于是不同版本,这里你得重新创建隐式验证版本的秘钥,由于隐式验证版本只是不展示复选框,改为使用按钮点击来触发图片选择验证,其它API,url属性等等都是一样的,这里我就直接给出一个完整的例子:
<-- html部分 -->
<button class="g-recaptcha" data-sitekey="客户端公钥" data-callback='onSubmit'>Submit</button>
<script src="https://www.recaptcha.net/recaptcha/api.js" async defer></script>
//js部分
function onSubmit(responToken) {
console.log(responToken);
alert('开始提交表单');
};
两种复选框模式与隐式验证模式请根据实际业务场景选择使用,不存在谁好谁坏。
肆 ❀ 服务端(后端)集成说明
说完客户端集成,我们来说下服务端如何集成,由于我没学过后端语言,这里就给不出例子了,具体说下怎么用。这里先解释下前后端怎么配合。
![](https://img2020.cnblogs.com/blog/1213309/202003/1213309-20200307185030440-2049453964.png)
如上图,我们来模拟一次完整的验证过程:
- 用户点击登录按钮(假设用的是隐式验证模式),弹出了图片选择框,用户选择完正确图片,点击了验证按钮。
- 这时其实会对谷歌发起请求,请求成功,前端拿到了
response token
。 - 前端请求与后端协商好的接口A,把
response token
带给后端。 - 后端拿着私钥与
response token
请求谷歌提供的接口地址B,成功并拿到了验证结果。 - 后端将这份数据再返回给前端,前端判断成功,这时才开始请求登录接口。
那么后端需要请求的接口地址B就是https://www.google.com/recaptcha/api/siteverify
,请求方式为POST
。
POST
参数有三个,我们来说下分别是什么:
secret(必填):私钥,也就是我们创建秘钥时,给服务端用的那个秘钥。
response(必填):response token
,这个由用户在前端操作后产生,有效期为2分钟,且只能用一次。
remoteip(选填):用户ip。
返回数据格式如下:
{
"success": true|false,
"challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string, // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...] // optional
}
错误码分类这里我就不列了,具体可以查看错误码说明。
有的同学一定会疑惑,用户操作完成前端不是已经知道验证成功失败了吗,何必多次一举还麻烦后端去请求呢。常理上来说,只通过前端验证也是可以的,只是后端无法感知。比如博主公司已经有了一套验证码系统,国内用这套,国外用谷歌这套,为了统一验证码验证规则,还是统一由后端提供验证码接口让前端调用,这个就看各位实际业务场景是什么样了。
好了,关于google recaptcha介绍到这里就结束了,如果有问题或疑问欢迎留言,我会在第一时间回复你。
那么到这里,本文正式结束。