首页 >后端开发 >php教程 >为什么我加了验证码,别人还是可以刷票呢?

为什么我加了验证码,别人还是可以刷票呢?

WBOY
WBOY原创
2016-06-23 13:05:381134浏览

为什么我加了验证码,别人还是可以刷票呢?下面是获取验证码的代码,是不是验证码太简单了,应该怎么弄复杂一点?

/**
 * 验证码图片类
*/

if (!defined('IN_FDYU'))
{
    die('Hacking attempt');
}

class captcha
{
    /**
     * 背景图片所在目录
     *
     * @var string  $folder
     */
 
    //var $folder = ROOT_PATH . 'includes/captcha/';

var $folder = '';

    /**
     * 图片的文件类型
     *
     * @var string  $img_type
     */
    var $img_type   = 'png';

    /*------------------------------------------------------ */
    //-- 存在session中的名称
    /*------------------------------------------------------ */
    var $session_word = 'captcha_word';

    /**
     * 背景图片以及背景颜色
     *
     * 0 => 背景图片的文件名
     * 1 => Red, 2 => Green, 3 => Blue
     * @var array   $themes
     */
    var $themes_jpg = array(
        1 => array('captcha_bg1.jpg', 255, 255, 255),
        2 => array('captcha_bg2.jpg', 0, 0, 0),
        3 => array('captcha_bg3.jpg', 0, 0, 0),
        4 => array('captcha_bg4.jpg', 255, 255, 255),
        5 => array('captcha_bg5.jpg', 255, 255, 255),
    );

    var $themes_gif = array(
        1 => array('captcha_bg1.gif', 255, 255, 255),
        2 => array('captcha_bg2.gif', 0, 0, 0),
        3 => array('captcha_bg3.gif', 0, 0, 0),
        4 => array('captcha_bg4.gif', 255, 255, 255),
        5 => array('captcha_bg5.gif', 255, 255, 255),
    );

    /**
     * 图片的宽度
     *
     * @var integer $width
     */
    var $width      = 38;

    /**
     * 图片的高度
     *
     * @var integer $height
     */
    var $height     = 16;

/**
     * 构造函数
     *
     * @access  public
     * @param
     *
     * @return void
     */
    function __construct($folder = '', $width = 38, $height = 16)
    {
        $this->captcha($folder, $width, $height);
    }

    /**
     * 构造函数
     *
     * @access  public
     * @param   string  $folder     背景图片所在目录
     * @param   integer $width      图片宽度
     * @param   integer $height     图片高度
     * @return  bool
     */
    function captcha($folder = '', $width = 38, $height = 16)
    {
$folder = ROOT_PATH . 'includes/captcha/';

        if (!empty($folder))
        {
            $this->folder = $folder;
        }

        $this->width    = $width;
        $this->height   = $height;

        /* 检查是否支持 GD */
        if (PHP_VERSION >= '4.3')
        {

            return (function_exists('imagecreatetruecolor') || function_exists('imagecreate'));
        }
        else
        {

            return (((imagetypes() & IMG_GIF) > 0) || ((imagetypes() & IMG_JPG)) > 0 );
        }
    }

    


    /**
     * 检查给出的验证码是否和session中的一致
     *
     * @access  public
     * @param   string  $word   验证码
     * @return  bool
     */
    function check_word($word)
    {
        $recorded = isset($_SESSION[$this->session_word]) ? base64_decode($_SESSION[$this->session_word]) : '';
        $given    = $this->encrypts_word(strtoupper($word));

        return (preg_match("/$given/", $recorded));
    }

    /**
     * 生成图片并输出到浏览器
     *
     * @access  public
     * @param   string  $word   验证码
     * @return  mix
     */
    function generate_image($word = false)
    {
        if (!$word)
        {
            $word = $this->generate_word();
        }

        /* 记录验证码到session */
        $this->record_word($word);

        /* 验证码长度 */
        $letters = strlen($word);

        /* 选择一个随机的方案 */
        mt_srand((double) microtime() * 1000000);

        if (function_exists('imagecreatefromjpeg') && ((imagetypes() & IMG_JPG) > 0))
        {
            $theme  = $this->themes_jpg[mt_rand(1, count($this->themes_jpg))];
        }
        else
        {
            $theme  = $this->themes_gif[mt_rand(1, count($this->themes_gif))];
        }

        if (!file_exists($this->folder . $theme[0]))
        {
            return false;
        }
        else
        {
            $img_bg    = (function_exists('imagecreatefromjpeg') && ((imagetypes() & IMG_JPG) > 0)) ?
                            imagecreatefromjpeg($this->folder . $theme[0]) : imagecreatefromgif($this->folder . $theme[0]);
            $bg_width  = imagesx($img_bg);
            $bg_height = imagesy($img_bg);

            $img_org   = ((function_exists('imagecreatetruecolor')) && PHP_VERSION >= '4.3') ?
                          imagecreatetruecolor($this->width, $this->height) : imagecreate($this->width, $this->height);

            /* 将背景图象复制原始图象并调整大小 */
            if (function_exists('imagecopyresampled') && PHP_VERSION >= '4.3') // GD 2.x
            {
                imagecopyresampled($img_org, $img_bg, 0, 0, 0, 0, $this->width, $this->height, $bg_width, $bg_height);
            }
            else // GD 1.x
            {
                imagecopyresized($img_org, $img_bg, 0, 0, 0, 0, $this->width, $this->height, $bg_width, $bg_height);
            }
            imagedestroy($img_bg);

            $clr = imagecolorallocate($img_org, $theme[1], $theme[2], $theme[3]);

            /* 绘制边框 */
            //imagerectangle($img_org, 0, 0, $this->width - 1, $this->height - 1, $clr);

            /* 获得验证码的高度和宽度 */
            $x = ($this->width - (imagefontwidth(5) * $letters)) / 2;
            $y = ($this->height - imagefontheight(5)) / 2;
            imagestring($img_org, 5, $x, $y, $word, $clr);

            header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');

            // HTTP/1.1
            header('Cache-Control: private, no-store, no-cache, must-revalidate');
            header('Cache-Control: post-check=0, pre-check=0, max-age=0', false);

            // HTTP/1.0
            header('Pragma: no-cache');
            if ($this->img_type == 'jpeg' && function_exists('imagecreatefromjpeg'))
            {
                header('Content-type: image/jpeg');
                imageinterlace($img_org, 1);
                imagejpeg($img_org, false, 95);
            }
            else
            {
                header('Content-type: image/png');
                imagepng($img_org);
            }

            imagedestroy($img_org);

            return true;
        }
    }

    /*------------------------------------------------------ */
    //-- PRIVATE METHODs
    /*------------------------------------------------------ */

    /**
     * 对需要记录的串进行加密
     *
     * @access  private
     * @param   string  $word   原始字符串
     * @return  string
     */
    function encrypts_word($word)
    {
        return substr(md5($word), 1, 10);
    }

    /**
     * 将验证码保存到session
     *
     * @access  private
     * @param   string  $word   原始字符串
     * @return  void
     */
    function record_word($word)
    {
        $_SESSION[$this->session_word] = base64_encode($this->encrypts_word($word));
    }

    /**
     * 生成随机的验证码
     *
     * @access  private
     * @param   integer $length     验证码长度
     * @return  string
     */
    function generate_word($length = 4)
    {
        $chars = '1234567890ABCDEFGHJKLMNPQRSTUVWXYZ';

        for ($i = 0, $count = strlen($chars); $i         {
            $arr[$i] = $chars[$i];
        }

        mt_srand((double) microtime() * 1000000);
        shuffle($arr);

        return substr(implode('', $arr), 5, $length);
    }
}

?>


回复讨论(解决方案)

只看到 check_word 的定义,没看到 check_word 的调用
也没看到 session_start

在提交页面里有调用的:
include_once('includes/cls_captcha.php');
$validator = new captcha();
if (!$validator->check_word($t_captcha))
{
$ajax['record']['all_tp'] = 9;
echo json_encode($ajax);
exit;
}

那 session_start(); 在哪里?

好像是没有,那怎么弄?

session_start(); 这个也有的,在另一个文件里

require(ROOT_PATH . 'includes/init.php');每个页面都有这个文件,session_start(); 就在这个文件里

你传入的 验证码在哪里?怎么没传给 $validator


                                          
                                          
                                          
                                          
                                           为什么我加了验证码,别人还是可以刷票呢?
                                          
                                        



js:
function get_toupiao(tp_id,all_toupiao,hd_id,tp_star_time,tp_end_time)
{
if($.trim($("input[name=captcha]").val()) == '1')
{
if($.trim($("input[name=t_captcha]").val()) == '')
{
alert("验证码不能为空!");
$("input[name=t_captcha]").focus();
return false;
}
}
var t_captcha=$.trim($("input[name=t_captcha]").val());
var captcha=$.trim($("input[name=captcha]").val());
var originator=$.trim($("input[name=originator]").val());
$.get("/show.php?act=get_toupiao",{
tp_id:tp_id,
all_toupiao:all_toupiao,
hd_id:hd_id,
tp_star_time:tp_star_time,
tp_end_time:tp_end_time,
t_captcha:t_captcha,
captcha:captcha,
originator:originator,
async:false,
rand: Math.random()
},function(data){
if(data.record.all_tp=="9")
{
alert("验证码输入错误^_^!");
                return false;
}
/*if(data.record.all_tp=="8")
{
alert("请进行有效投票哦^_^!");
                return false;
}
if(data.record.all_tp=="7")
{
alert("同时投票的人太多,请稍候重试^_^!");
                return false;
}*/
if(data.record.all_tp=="5")
{
alert("今天您已经投票,请明天再投吧!");
                return false;
}
if(data.record.all_tp=="6")
{
alert("今天您已经投票,请明天再投吧!");
                return false;
}
if(data.record.all_tp=="3")
{
alert("投票时间已过,不能投票");
                return false;
}
if(data.record.all_tp=="4")
{
alert("投票时间还没到,不能投票");
                return false;
}
if(data.record.all_tp=="1")
{
alert("该活动您已投票,不能重复投票");
                return false;
}
if(data.record.all_tp=="2")
{
alert("该项目您已投票,不能重复投票");
                return false;
}
if(data.status.code=="1")
{
//成功
$("#tp_"+tp_id+"").empty();
$("#tp_"+tp_id+"").append(""+data.record.tp_count+"");
$("#captcha_"+tp_id+"").empty();
$("#captcha_"+tp_id+"").append(""+data.status.captcha+"");
alert("投票成功!");
                return false;
}
},"json");
}

PHP:
elseif($action == 'get_toupiao')
{
global $fdyu,$db;
$tp_id = intval($_GET['tp_id']);
$hd_id = intval($_GET['hd_id']);
$all_toupiao = $_GET['all_toupiao'];
$tp_star_time = $_GET['tp_star_time'];
$tp_end_time = $_GET['tp_end_time'];
$t_captcha = $_GET['t_captcha'];
$captcha = intval($_GET['captcha']);
$ip=getClientIP();
$ajax = array();

//是否需要验证码
if($captcha==1)
{
include_once('includes/cls_captcha.php');
$validator = new captcha();
if (!$validator->check_word($t_captcha))
{
$ajax['record']['all_tp'] = 9;
echo json_encode($ajax);
exit;
}
}

提供检查思路:
1.如果输入为空是否可以通过
2.把输入的验证码和session的验证码打印出来看看
3.验证通过后,需要把旧的验证码删除,否则用户可以不刷新页面,一直用这个验证码提交不同的数据

可以参考: http://blog.csdn.net/fdipzone/article/details/7295496

 以前刷Yii哥帖子时发现csdn就有楼上说的第3个bug,不过刷完转天他们就修复了
验证码防刷票是个很不靠谱的东西,如果投票数牵扯到利益,那用户完全可以去买付费的验证码识别
我觉得归根到底还是得IP去重

IP限了,但也没用,刷票软件可以刷不同的IP

10楼,我发现确实是像你说的第三点,因为我在数据库里记录了验证码,发现有重复的验证码!那怎么删除旧的验证码呢?

if($action == 'get_toupiao')
{
。。。。。。省略
if ($_SESSION['code_1']!=$t_captcha)
{
    $ajax['record']['all_tp']   = 9;
    echo json_encode($ajax);
    exit;
}
。。。。。省略
$ajax['status']['code'] = 1; //成功
echo json_encode($ajax);
exit;
}

是在$ajax['status']['code'] = 1; //成功这个上面加unset($_SESSION['code_1']);这个吗?

就是通过验证后,把session的验证码清空就可以了。
保证令牌只能用一次

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn