php登录验证码页面完整代码
登录验证码这东西,登代码说穿了就是录验给登录接口加一道门槛。没有它,证码别人写个脚本就能拿字典跑你的页面后台。PHP做验证码不需要GD库以外的完整依赖,代码量也不大,登代码但细节没处理好,录验等于白做。证码 我见过不少人直接把验证码文字存session就完事,页面结果前端刷新页面不换图,完整或者验证码字符集用了0和O、登代码1和l这种容易混淆的录验,用户输错三次直接骂人。证码下面这份代码,页面我改过几版,完整目前用在几个小项目上,够用。 新建一个captcha.php,核心逻辑是:开session、生成随机码、画图、存session。 imagestring用的内置字体,效果一般但不用额外字体文件。想好看点可以用imagettftext加载ttf,但路径问题容易踩坑,小项目没必要。 表单里放一个输入框和验证码图片,点击图片刷新。注意刷新时加个随机参数,不然浏览器走缓存。 那个onclick里的Math.random()是关键。不加的话,用户点击图片,浏览器发现URL没变,直接用缓存,验证码根本不换,session里的值也没更新。 check.php里先比对验证码,再查数据库。顺序别搞反,验证码错了直接挡掉,省得浪费数据库查询。 这里有个坑:验证码比对完必须销毁。不销毁的话,同一个验证码可以反复提交,等于没加。另外strtolower统一转小写,生成时存的是小写,用户输入大写也能过,体验好一点。 session跨域或者子域名共享时,验证码存不进去。检查session.cookie_domain配置,或者干脆用cookie存hash值,但安全性差一些。 还有一点,captcha.php输出图片前不能有任何输出,包括BOM头和空格。我遇到过有人在 最后,验证码不是万能的。简单脚本用OCR能识别这种基础验证码,真要防刷还得上行为验证或者短信验证。但日常挡掉90%的暴力尝试,这套代码够了。先看生成验证码的PHP文件
<?php session_start(); // 字符集去掉了0、O、1、I、l这些 $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; $code = ''; for ($i = 0; $i < 4; $i++) { $code .= $chars[mt_rand(0, strlen($chars) - 1)]; } // 存session,注意key名别太通用 $_SESSION['login_captcha'] = strtolower($code); // 图片尺寸 $width = 120; $height = 40; $image = imagecreatetruecolor($width, $height); // 背景色,浅灰偏白 $bgColor = imagecolorallocate($image, 245, 245, 245); imagefill($image, 0, 0, $bgColor); // 画干扰点 for ($i = 0; $i < 80; $i++) { $dotColor = imagecolorallocate($image, mt_rand(150, 220), mt_rand(150, 220), mt_rand(150, 220)); imagesetpixel($image, mt_rand(0, $width), mt_rand(0, $height), $dotColor); } // 画干扰线,2条就够,太多影响识别 for ($i = 0; $i < 2; $i++) { $lineColor = imagecolorallocate($image, mt_rand(100, 180), mt_rand(100, 180), mt_rand(100, 180)); imageline($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $lineColor); } // 写字符,每个字符随机倾斜和位置偏移 for ($i = 0; $i < 4; $i++) { $charColor = imagecolorallocate($image, mt_rand(20, 80), mt_rand(20, 80), mt_rand(20, 80)); $x = 15 + $i * 25 + mt_rand(-3, 3); $y = mt_rand(15, 25); imagestring($image, 5, $x, $y, $code[$i], $charColor); } header('Content-Type: image/png'); imagepng($image); imagedestroy($image); ?> 登录页面的HTML部分
<form action="check.php" method="post"> <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="text" name="captcha" placeholder="验证码" maxlength="4"> <img src="captcha.php" id="captchaImg" onclick="this.src='captcha.php?t='+Math.random()" style="cursor:pointer;vertical-align:middle;"> <button type="submit">登录</button> </form> 验证逻辑
<?php session_start(); $inputCaptcha = isset($_POST['captcha']) ? strtolower(trim($_POST['captcha'])) : ''; if (empty($_SESSION['login_captcha']) || $inputCaptcha !== $_SESSION['login_captcha']) { // 验证码错误,销毁session里的验证码,防止重复使用 unset($_SESSION['login_captcha']); exit('验证码错误'); } // 验证码用一次就销毁 unset($_SESSION['login_captcha']); // 后面接你的用户名密码验证逻辑 // ... ?> 几个实际遇到的问题
<?php前面多了个空行,图片死活显示不出来,排查半天。
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-