验证码校验的玩法

验证码的校验原理其实很简单:

  1. 客户端请求验证码;
  2. 服务端生成校验码(code_key-code_value),code_key是一次验证码请求和校验的标识(也有称会话id),会返回给客户端;code_value表示正确的验证码(通常以字符串表示);如果是图片这类的验证码,则需要将图片输出到客户端。
  3. 用户输入验证码(input_code_value);
  4. 客户端会将code_key和输入的验证码(input_code_value)发送至服务器进行校验,如果input_code_value=code_value则表示校验通过。

而我们下面要探讨的是,在不同场景下,处理校验码的一些方案;主要包括验证码存在哪里、由谁来校验、怎么校验这几个方面。

1. 单台服务器验证码校验(session)

相信大家都有了解session的原理,客户端访问服务器后,服务端给客户端返回一个叫JSessionId的cookie,服务器可以根据这个值来标识本次会话。单台服务器下,session是一个不错的验证码存储的地方,我们不用担心各个会话间的验证码存在冲突。
用户登录+图片验证码+session 为例,其流程主要为:

用户登录+图片验证码+session

这里code_key可以理解成JSessionId+session.attribute中的key(这里是"code")

2. 服务器集群下的服务器校验(MySQL/Redis)

当单个服务(如用户中心)使用多台服务器部署后,因为需要做负载均衡,一般情况下(暂不考虑IP-hash那样的策略),用户每次发起的请求有可能会去到不同的服务器,这时候session就会失效了,因为JSessionId这个标志去到别的服务器是找不到对应的session的(事实上,传统的session已经慢慢退出江湖)。
这时候,我们需要自己掌控code_key的生成和存储,关系型数据库(如MySQL)或高性能的NoSQL数据库(如Redis)都是不错的选择。以 用户登录+图片验证码+redis 为例:

用户登录+图片验证码+redis

可以看到,与单台服务器主要差距在:

  1. 自己生成code_key(为了防止不同用户间验证码的冲突,生成规则通常与用户标识有关,比如用户id+随机数的组合转换),不再依赖JSessionId;
  2. 验证码的存储的地方从session转移至redis。

3. 各司其职,分布式下的验证码校验(验证中心)

在上面两种方式,我们发现验证码的生成、存储、校验、业务处理等动作均是在业务方完成的,验证码逻辑和业务的耦合可能会导致一些问题:

  1. 验证码的风险(比如机器识别难度低、验证接口被攻击等)将由业务方来承担,而业务方往往不愿意投入过多的精力在上面;
  2. 当我们需要升级验证码方式时(比如图片文字识别 -> 文字点击顺序/拖动/手机验证码等),往往需要服务器做出不小改动和发版,成本较高。

为了解决上面的这些问题,我们可以建立一个专门搞验证的服务——验证中心

  1. 验证中心负责各种类型的验证码校验和存储(如采用MySQL/redis,校验方案与集群的那种一致),并提供足够安全的验证码类型供业务方选择;
  2. 输出验证码(code_key)和第一次校验由客户端和验证中心完成,业务方不参与该阶段验证
  3. 验证中心第一次校验成功后生成对应的ticket(比如uuid)给客户端,业务方需要根据code_key和ticket到验证中心进行二次校验,确保验证结果有效。

仍以用户登录为例,我们现在来看看初步的方案:


初步流程

我们需要明白的是,客户端一共发起三次请求:(1)请求验证中心输出验证码(2)请求验证中心校验验证码(3)请求业务方二次校验并处理业务。
这个初步的方案并不完美,因为在第(3)个请求,也就是二次校验时,只要code_key-ticket相互对应都会通过,这会导致:

  1. 不同的业务系统间的code_key-ticket混用;本来是业务A系统接口下(比如社区的回贴)所需的图形验证码,经过验证中心首次校验后,产生的code_key-ticket,直接拿到业务B系统接口下(比如支付系统的转账)依然适用(攻击者便可以轻松跳过转账接口的较为严格的首次校验);
  2. 同一个业务系统,不同接口间的code_key-ticket混用;本来是业务A系统【接口1】下产生的code_key-ticket,拿到A系统的【接口2】上依然适用;

为了解决以上问题,针对每个业务方,验证中心需要分配一个的账号(也就是我们常见的app_id和app_secret);
针对某个业务方下的每个需要验证码的业务接口,需要分配一个的id(姑且叫business_id),它标识了对应的业务和接口,以及使用什么类型的验证码(当然这个类型应该支持动态配置),其关系如下:

app_id和business_id的关系

加入这些元素后,我们的流程基本不变,只不过多了一些参数校验而已,最终的流程:


验证中心完整流程

也有一些方案是没有business_id这个东西的,他们的business_id等同于app_id,一个业务方中也就只有一个。像我司的验证中心就是一个app_id,客户端、业务方均使用这个。这个主要看大家的细粒度需要分成什么程度了

4.总结

验证码实现方式 实现成本 优缺点
session 只适用于单机;安全性依赖于业务团队水平
业务方+MySQL/Redis 实现相对简单,能满足大部分使用场景 ;不够灵活,变动成本相对较高;安全性依赖于业务团队水平;各个业务系统需要自己搞一套,总的性价比不高。
验证中心+MySQL/Redis 给业务方提供足够的安全性以及便利性(客户端/服务端对接验证中心提供插件支持,对接成本低);验证码类型的升级/变更,服务端不需要进行代码变更;前期验证中心的搭建投入成本较高,需要保证足够的tps支持业务需求,但一旦项目成熟,后期回报可观。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容