验证码的作用
定义:
全自动区分计算机和人类的公开图灵测试
英语:完全自动化的公共图灵测试,告诉计算机和人类
俗称验证码,缩写为Captcha。
首先,需要明白:
验证码是种反人类的存在。但它短时间内不可能退出历史舞台。我们需要尽量优化它,尽量提升用户的体验。
为什么要有验证码呢?
是为了证明网络的那端是一个人而不是一台机器(电脑)。
为什么要区分是人还是机器呢?
原因很多,归根结底,在于做坏事上,机器的效率比人高,成本比人低!
示例,臭名昭著的百度,极其恶心的验证码:
下面是验证码的几种常用场景:
- 账号安全。比如登录窗口,如果不设置验证码,可以使用脚本进行暴力**。
- 防作弊。比如,12306的验证码是为了防止机器恶意刷票。
- 反垃圾消息。比如,某些论坛上的验证码,防止机器群发的垃圾广告广告。
下面是几种常见可视化验证码的形式:
- 歪曲的字
- 倒立,点击
- 问答题
- 滑动拼图验证码
- 其他各种五花八门
他们有一个共同点,机器不容易辨认,可人类很容易就能识别。
现在,验证码技术也在不断发展。尤其是基于大数据的智能判断方兴未艾,按下不表。
验证码的原理
一个完整的验证逻辑分两步:
-
第一次请求
- 服务器生成一个可以比较的对象,比如字符串或数字,并将其保存起来。一般保存到会中。
- 服务器根据上述生成的对象,构造出机器难以辨识的一段数据,比如声音,图片或短信,并发送给用户。
- 数据在客户端展示,用户可以去识别。
-
第二次请求,携带用户输入的验证信息(校验阶段)
- 用户将自己的数据,连带辨识出来的验证码数据,一并请求到服务器
- 服务器将之前保存的原始数据,跟用户提交的作比较。如果相同,那么通过,否则不通过。
图片验证码
这是一种最基本的验证方式,其他所有的验证思路都是跟着一致的。
Java中,绘制图片,需要用到awt
包的BufferedImage
类。
在获取阶段,客户端代码描述为:
< img src = “ / captcha ” title = “验证码” />
< input name = “ captcha ” />
服务端的代码描述为:
@WebServlet(“ / captcha ”)
类 CaptchaServlet {
public获得验证码的方法(){
// 1.获取随机字符串,作为原始验证字符串
String randomString = getRandomString(4);
// 2.根据字符串,生成机器难以辨认的图片
BufferedImage image =绘制图片(randomString);
// 3.原始字符串 - >保存起来
会话。setAttribute( “ captcha ”,randomString);
// 4.绘制的图片 - >发送给用户
ImageIO 。写(图像, “ PNG ”,响应。的getOutputStream());
}
/ *根据字符串绘制图片* /
BufferedImage绘制图片(String randomString){
// 1.创建图片对象
的BufferedImage图像 = 新 的BufferedImage(W,H, BufferedImage的。 TYPE_INT_RGB);
//获取画笔
图形 g = image。的getGraphics();
// 3.设置背景色
g。的setColor(getRandomColor());
g 。fillRect(0,0,W,H);
//绘制字符串
g。的setColor(getRandomColor());
g 。setFont(new Font(xxx,xxx,xxx));
g 。drawString之();
//其他一些处理,变形扭曲等
// 5.画干扰线和干扰点等
g。的setColor(getRandomColor());
g 。的drawLine();
g 。drawOval();
// 6.结束
g。处置();
返回图像
}
}
短信验证码
除了上述直接发送给用户浏览器的可视化验证码之外,在注册等场合,我们经常用到短信或邮箱验证。
这主要是为了防止账号被随意注册,从而进行恶意行为(僵尸粉,刷单等),也是奸商获取我们私人信息的重要途径(其实是为了提供更优服务哦〜)。
有时候也是为了代替密码,绑定手机用来确保登录的安全性。
小朋友,将你的所有秘密都告诉我,我会给你糖吃〜由麻云
不管是图片验证码,还是短信,邮箱验证,道理都是一样的,区别在于发送给用户去辨认的数据不同,数据展示方式不同或数据接收媒介不同。
短信验证
也是分为验证码获取和校验两个阶段!获取验证码这一步通常通过Ajax实现,并在服务端调用短信接口发送数据,数据不再通过浏览器展现,而是通过手机等其他媒体传递。
短信验证的简单代码描述为:
//请求中得到用户的手机号码
String phone = request。getParameter( “ phone ”);
// 2.得到随机的字符串或数字
String randomNumber = getRandomNumber( 4);
// 3.将得到的原始字符串保存起来
会话。setAttribute( “ captcha ”,randomNumber);
// 4.调用短信接口服务,将原始字符串发送给用户
SMSInteface 。sendMessage(phone,randomNumber);
至于短信接口服务,有很多。比如阿里大鱼,它的使用很简单:
// 1.注册账号,获取appkey和secret
// 2.申请短信签名,申请短信模板
// 3.为项目添加jar包:“com.aliyun:aliyun-java-sdk-dysmsapi:+”
// 4编写程序,发送短信
public void sendMessage( String phone, String randomNumber){
// 1.构造请求对象
AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
REQ 。setRecNum(电话); //发给谁
REQ 。setSmsType(“ normal ”); //短息类型
req 。setSmsFreeSignName(“南方IT学院134班”); //你的签名
REQ 。setSmsTemplateCode(“ SMS_585014 ”); //模板,需要自己在后台设置
REQ 。setSmsParamString(“ {,\” body \“:\” “ + randomNumber+ “ \” } “); //发送内容,以参数形式传递给模板
// 2.发送短信,生成响应对象
TaobaoClient client = new DefaultTaobaoClient( “ http://gw.api.taobao.com/router/rest ”,appkey,secret);
AlibabaAliqinFcSmsNumSendResponse resp =客户端。执行(REQ);
系统。出。的println(相应。 getBody());
}
就这么简单。
邮箱验证码
邮箱验证,需要用到J2EE的Java Mail标准。
国外的网站,基本都是使用邮箱注册。它很基础很重要。
但道理相通,时间有限,在此略过不提。