验证码的实现

  1. 验证码是什么?
  2. 为什么要验证码?
  3. 怎么实现验证码?

什么是验证码?

简单的说,英文简称是captcha,全称叫"Completely Automated Public Turing Test To Tell Computers and Humans Apart".意思是"自动区分人类与计算的图灵测试".翻译成人话是:证明你是人,证明你是你.

为什么要验证码?

防止机器人模拟人去做无意义的事,机器人也就程序员.现在验证码越来越难就是程序员相互撕逼的结果.
天下无码,只有天下无贼.

怎么实现验证码?

重点,验证码实现思路,验证码目的是为难计算机,不为难人.
常见的验证码归纳为两种

证明你是人

人和计算机主要区别是:正常人有主观意识,正常的电脑没有
常用方式:

  1. 文本验证码
    如:一加一等于几?
  2. 图形验证码
    如:看图写字,挑选相同,找你妹
  3. 语音验证码
    如:听写模式和读文字模式
  4. 互动验证码
    如:拖动一下,滑动一下,按规则点击
  5. 形为验证码
    如:谷哥的形为验证码.主要利用收集设备或账户的上网形为数据,分析是出是人是鬼.

证明你是你

用来证明你是本人在操作,常邮方式:

  1. 手机短信验证码
    注册账号是常用,证明手机号是你的.有收短信和发短信两种
  2. 手机语音验证码
    收到一个电话录音,输入录音内容
  3. 邮箱,即时通工具接收验证码
  4. 生物识别
    指纹识别,语音识别,人脸识别
  5. 朋友圈验证码
    利用朋友圈关系,由多个朋友同时验证,常见于密码找回.

技术实现

主要讲"证明你是人"的web技术实现方式.
从方式看可以看出,就是一个猜迷语游戏,所有验证码都有5个共同点:
1.迷面
2.答案
3.出题者
4.时效性
5.随机性

迷面:给用户的问题,问题可以用文字,图片,语音,动作等来体现.
迷底:根据迷面内容猜出答案.
出题者:谁问的问题,只能答谁的
时效性:每个问题都有有效时间,在规定时间内答题才算完成.限制答题次数
随机性:不可预见,题面每次都随机性变化

根据这几个特点.介绍web中的3种实现原理.
以图形验证码为例,

1.Session实现

这是最常见的方式,基础入门时便使用这种方式.
现实原理:
第1步 ,服务端随机生成一串文字(迷底)
第2步, 把存迷底放到session中
第3步, 生成迷面的图形
第4步, 检查用户输入和session中迷底是否一致

特点是:实现方式简单,适合单机项目
缺点是:全局session不必要的内存消耗;不适合多机布署.
流程图:


验证码的实现_第1张图片
image.png

2, 基于对称加密算法

使用客户端存储代替服务端存储,图片可以使用base64位
原理:
第一步:生成随机串
第二步:把随机串+时间戳+客户端标识+干扰串,用DES加密,得到密串
第三步:用随机串生成图片
第四步:把随机图片+密串保存到客户端
第五步:服务端解密密串,对比用户输入

优点:可以分布式,不占用服务器存储.不用维护seesion.
缺点:解密占用CPU

验证码的实现_第2张图片
image.png

3,基于数据库

为提高性能,常使用redis来作为存储,现常用的方式,主要介绍一下.
第1步,生成随机串和token
第2步,使用token作为hashMap的键,存储随机串,时间,客户端信息,应用信息
第3步,返回token和随机串图片给客户端
第4步,验证客户端输入和token的内容有效性

优点:基于token可以分布式,不占用全局内存,验证码与业务独立
缺点:占用服务器存储空间,需要维护session和清理垃圾数据

示例,多端,全站统一验证码通用解决方案
1.前端向服务端API请求验证码

  1. 服务端返回验证码类型,验证码需要的数据
  2. 前端根据类型渲染出UI(如图形,文字,拖动框等).
  3. 前端先验证
  4. 根据业务后端再次验证

交互图

验证码的实现_第3张图片
image.png

服务端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作好过期策略和防垃圾攻击.

你可能感兴趣的:(验证码的实现)