同福

做个用户管理系统(19)——验证码的实现【20201206】

介绍

介绍

今天福哥打算使用TFPHP框架的TFSafeCode对象给我们的TFUMS系统的注册功能增加验证码功能,大家可以通过这个注册功能的验证码功能了解到验证码是怎么一回事、验证码的工作原理以及验证码在表单当中的作用和价值。

验证码简单说就是:防止机器人模拟用户操作表单的安全防护措施。

也就是说,我们给表单增加验证码机制的目的仅仅是为了避免黑客使用程序/机器人模拟用户操作表单提交数据。那么验证码的作用就是让机器很难识别正确结果,而真正的用户又相对容易想出正确结果,从而达到将机器操作屏蔽的目的。验证码的价值体现在不让机器去操作我们的功能表单,机器操作表单不是我们设计网站平台的期望结果,而且机器还有可能通过一些技术破解用户账号密码给系统造成安全问题,所以使用验证码在很多场景下面是必须的。

验证码控制器

验证码控制器用于显示一张包含验证码的图片,控制器存放在WEB-INF/Controller/api/image/safeCode.inc.php里面。

代码

protected function process(){
    $req = $this->tfphp->getRequest();
    $mySafeCode = new TFSafeCode($this->tfphp);
    // create safecode
    $length = 4;
    $mySafeCode->create(array(
        'length'=>$length,
        'type'=>TFSafeCode::T_LC_TYPE_NUM
    ));
    $code = $mySafeCode->getCode();
    $sn = $mySafeCode->getSN();
    // save sn into cookie
    $req->cookie->setCookie("safeCode_". $req->get->get("key"), $sn, null, $req->server->get("BASE_URI"));
    // create image and write code
    $imgWidth = 4*18;
    $imgHeight = 38;
    $im = imagecreatetruecolor($imgWidth, $imgHeight);
    $bkColor = imagecolorallocate($im, rand(198, 255), rand(198, 255), rand(198, 255));
    imagefill($im, 0, 0, $bkColor);
    for($i=0;$i<$length;$i++){
        // font size
        $size = 23;
        // rotate
        $range = rand(-15, 15);
        // xy
        $x = $i*$size*0.68+5;
        $y = 30;
        // color
        $color = imagecolorallocate($im, rand(0, 168), rand(0, 168), rand(0, 168));
        // write
        imagettftext($im, $size, $range, $x, $y, $color, WEB_INF_ROOT_PATH. "Fonts/simhei.ttf", $code[$i]);
    }
    // show image
    header('Content-Type: image/jpeg');
    imagejpeg($im);
}

注册表单

增加了验证码之后的注册表单的JS部分也需要进行一些调整以对接验证码功能。

验证码html

<div class="form-group">
    <label>验证码</label>
    <div style="overflow: hidden; vertical-align: middle;">
        <input class="form-control form-vsn" type="text" name="vsn" style="float: left;" />
        <img id="safecode" style="display: none; float: left; margin-left: 6px;" />
        <a id="safecode-refresh" href="JavaScript:void(0)" style="float: left; margin-left: 6px; margin-top: 6px;">看不清?换一个!</a>
    </div>
</div>

验证码初始化

$('#safecode-refresh').click(function () {
    $('#safecode').attr('src', "<% $TFReq->server->BASE_URI %>api/image/safeCode?key=register&rnd="+Math.random());
    $('#safecode').show();
});
$('#safecode-refresh').trigger('click');

验证码刷新

if(d.errcode == 1001004){
    $('form').tips({
        text:"验证码错误"
    });
    $('#safecode-refresh').trigger('click');
}
else{
    $('form').tips({
        text:d.errmsg
    });
}

讲解

验证码控制器

验证码控制器的作用是显示一张包含验证码的图片,要使用PHP显示一张图片的话需要借助GD图像库,这里的image开头的函数都是GD图像库提供的。

首先调用TFSafeCode的create方法创建验证码和私钥,验证码留着画在图片里面,而私钥就放入Cookie里面后面交个注册控制器使用。

接着使用GD图像库创建图像,填充背景颜色,循环将验证码的每一个数字混上不同的颜色并倾斜不同角度画到图像上面。

最后将画好的图像以jpg格式显示出来,这里需要使用PHP指定MIME类型。

注册表单

验证码html

验证码分为三个部分,包括输入框、验证码图片、“看不清,换一张”几个元素。

输入框给用户填写表单时候用的。

验证码图片就是给用户看的,机器是很难“看”清楚的。

“看不清,换一张”就当用户以肉眼看不清图片上的数字的时候可以点击这里换一张验证码图片。

验证码初始化

这里就是驱动验证码的“看不清,换一张”的链接的功能的。

页面加载完成后会自动“点”一下链接,让验证码图片显示出来。

验证码刷新

这个是服务器处理结果时候的逻辑,如果错误码是1001004就表示是验证码填写错误了,我们除了提示用户之外还要更换一个新的验证码图片。

ce31b0f55ea8dae3.jpg

总结

今天福哥带着童鞋们实现了注册表单的验证码功能,这下注册表单的功能就彻底做完了!在制作注册表单的时候,我们把制作表单的全部知识点都学习了一遍,基本上一般的表单无出其右了!

下一课,福哥将带着大家完成登录表单的功能,届时会用到Redis这个数据库的功能。