- 验证码是什么?
- 为什么要验证码?
- 怎么实现验证码?
什么是验证码?
简单的说,英文简称是captcha,全称叫"Completely Automated Public Turing Test To Tell Computers and Humans Apart".意思是"自动区分人类与计算的图灵测试".翻译成人话是:证明你是人,证明你是你.
为什么要验证码?
防止机器人模拟人去做无意义的事,机器人也就程序员.现在验证码越来越难就是程序员相互撕逼的结果.
天下无码,只有天下无贼.
怎么实现验证码?
重点,验证码实现思路,验证码目的是为难计算机,不为难人.
常见的验证码归纳为两种
证明你是人
人和计算机主要区别是:正常人有主观意识,正常的电脑没有
常用方式:
- 文本验证码
如:一加一等于几? - 图形验证码
如:看图写字,挑选相同,找你妹 - 语音验证码
如:听写模式和读文字模式 - 互动验证码
如:拖动一下,滑动一下,按规则点击 - 形为验证码
如:谷哥的形为验证码.主要利用收集设备或账户的上网形为数据,分析是出是人是鬼.
证明你是你
用来证明你是本人在操作,常邮方式:
- 手机短信验证码
注册账号是常用,证明手机号是你的.有收短信和发短信两种 - 手机语音验证码
收到一个电话录音,输入录音内容 - 邮箱,即时通工具接收验证码
- 生物识别
指纹识别,语音识别,人脸识别 - 朋友圈验证码
利用朋友圈关系,由多个朋友同时验证,常见于密码找回.
技术实现
主要讲"证明你是人"的web技术实现方式.
从方式看可以看出,就是一个猜迷语游戏,所有验证码都有5个共同点:
1.迷面
2.答案
3.出题者
4.时效性
5.随机性
迷面:给用户的问题,问题可以用文字,图片,语音,动作等来体现.
迷底:根据迷面内容猜出答案.
出题者:谁问的问题,只能答谁的
时效性:每个问题都有有效时间,在规定时间内答题才算完成.限制答题次数
随机性:不可预见,题面每次都随机性变化
根据这几个特点.介绍web中的3种实现原理.
以图形验证码为例,
1.Session实现
这是最常见的方式,基础入门时便使用这种方式.
现实原理:
第1步 ,服务端随机生成一串文字(迷底)
第2步, 把存迷底放到session中
第3步, 生成迷面的图形
第4步, 检查用户输入和session中迷底是否一致
特点是:实现方式简单,适合单机项目
缺点是:全局session不必要的内存消耗;不适合多机布署.
流程图:
2, 基于对称加密算法
使用客户端存储代替服务端存储,图片可以使用base64位
原理:
第一步:生成随机串
第二步:把随机串+时间戳+客户端标识+干扰串,用DES加密,得到密串
第三步:用随机串生成图片
第四步:把随机图片+密串保存到客户端
第五步:服务端解密密串,对比用户输入
优点:可以分布式,不占用服务器存储.不用维护seesion.
缺点:解密占用CPU
3,基于数据库
为提高性能,常使用redis来作为存储,现常用的方式,主要介绍一下.
第1步,生成随机串和token
第2步,使用token作为hashMap的键,存储随机串,时间,客户端信息,应用信息
第3步,返回token和随机串图片给客户端
第4步,验证客户端输入和token的内容有效性
优点:基于token可以分布式,不占用全局内存,验证码与业务独立
缺点:占用服务器存储空间,需要维护session和清理垃圾数据
示例,多端,全站统一验证码通用解决方案
1.前端向服务端API请求验证码
- 服务端返回验证码类型,验证码需要的数据
- 前端根据类型渲染出UI(如图形,文字,拖动框等).
- 前端先验证
- 根据业务后端再次验证
交互图
服务端API接口,
1, GET /captcha 获取验证码接口
{
"error_code":0,
"data":{
"captcha_token":"adf242343fdfdgdfg2322",//验证码token
"captcha_type":"image",//验证类型
"captcha_res":"base64png24,xxxxx",//验证资源数据
"captcha_ttl":3600,//验证码有效时长
}
}
2, POST /captcha/validate 验证验证码
params:
token,验证码token
value,验证码输入的值(字符串,轨迹等)
{
"error_code":0,//错误码,根据错误码作不同操作,如超时刷新
"data":""
}
3, GET /captcha/token
获取验证码的详情,验证情况.可以是服务器内部服务调用,也可以客户端调用.业务根据验证码详情做出反馈.
"error_code":0,
"data":{
"token":"aaaaxxxxx",//token
"status":"success",//状态,成功后才能继续业务
"expire":"2017-09-18 22:10",//失效时间
"valid_counter":2,//验证计数器,
"ip":"9.9.9.9",//客户端IP地址
"guid":"xxx-xx-ss-xxss-xx",//客户端唯一标识
"app":"h5:/user/reg",//应用标识
...
}
后话,
根据不同安全级别,可以限制IP地址与客户端,验证次数.避免跨设备验证的情况(如打码).
使用redis作好过期策略和防垃圾攻击.