自定义滑动验证码

来源:https://github.com/plbin97/Antiboter-php-html-Chinese

1.将方法合并到一个类中

<?php
/**
 * Created by PhpStorm.
 * User: lxd
 * Date: 2018/8/20
 * Time: 15:36
 * Comm:验证码类 git : https://github.com/plbin97/Antiboter-php-html-Chinese
 */
namespace Partner\Logic;

use Think\Exception;

class VerificationLogic
{
    /*
     * Class Verification is used for storing the verification information.
     * The objects of this class usually would be stored in Session variable.
     *
     * The construction function would automatically generate the verification randomly.
     *
     * */
    private $img;
    private $x;
    private $y;
    private $verified;
    private $dir;
    private $error_allow; // is the error range which is accepted from the x and y coordinates which are sent from client. From 0 - 150

    public function __construct() {
        $this -> dir = "./public/images";
        $this -> x = rand(0,250);
        $this -> y = rand(0,150);
        $this -> verified = false;
        $this -> error_allow    = 10;
        $this -> img = rand(1,$this->getFilesNumber());
    }
    public function getPositionX() {
        /*
         * function getPositionX(): Get the small box horizontal location in x-axis, from 0 - 250;
         * return integer value.
         * */
        return $this -> x;
    }
    public function getPositionY() {
        /*
         * function getPositionY(): Get the small box vertical location in y-axis, from 0 - 150;
         * return integer value.
         * */
        return $this -> y;
    }
    public function getImg() {
        /*
         * function getImg(): Get the image file name, and those file names are numbers;
         * return integer value.
         * */
        return $this -> img;
    }
    public function isVerified() {
        /*
         * function isVerified(): get the verification status.
         *
         * return true if the verification is passed.
         *
         * Usually, you can also use $_SESSION["anti_bot_verified"] value to know if the verification is passed.
         * Means:
         *     isVerified() == $_SESSION["anti_bot_verified"]
         * */
        return $this -> verified;
    }
    public function verify($inputX,$inputY) {
        /*
         * function verify(): verify the X and Y position from users and return the result.
         *
         * para $inputX: X-coordinate of the small box. Range: 1 - 250
         *
         * para $inputY: verify the Y-coordinate of the small box. Range: 1 - 150
         *
         * return true means that the user is verified and is not a robot
         *
         * return false means that the verification is not passed, and the program automatically generate a new set of verification.
         *
         * The error range which is accepted can be configured in config.php
         * */
        if ($inputX < ($this -> x + $this->error_allow) && $inputX > ($this -> x - $this->error_allow) && $inputY < ($this -> y + $this->error_allow) && $inputY > ($this -> y - $this->error_allow)) {
            $this -> verified = true;
            return true;
        } else {
            return false;
        }
    }

    private function getFilesNumber()
    {
        /*
         * Function getFilesNumber() is used for counting how much files under a folder.
         * Parameter $directory: The directory of that folder
         * Return: Number of files under that directory.
         * */
        $file_count = 0;
        $files = glob($this->dir . "/verify_*.jpg");
        if ($files){
            $file_count = count($files);
        }
        return $file_count;
    }

    public function getImage( $data )
    {
        if( empty( $data['type'] ) )
            throw new Exception( '非法参数' );

        if( !in_array( $data['type'], ['large_picture','small_picture','original_picture'] ) )
            throw new Exception( '非法参数.' );

        if( !function_exists( 'imagecreatefromjpeg' ) )
            throw new Exception( '服务器异常,请加载php-gd库' );

        // Get the X and Y coordinate  from Session variables
        $position_x_1 = $this -> getPositionX();
        $position_y_1 = $this -> getPositionY();

        // Calculate the diagonal coordinate for that square
        $position_x_2 = $position_x_1 + 50;
        $position_y_2 = $position_y_1 + 50;

        // Get the image from local file. The image must be 300*200 size.
        $img_path = $this->dir . "/verify_" . $this -> getImg() . ".jpg";
        $img = imagecreatefromjpeg($img_path);
        if( !$img )
            throw new Exception( '未找到图片信息' );

        $image_size = getimagesize($img_path);

        // Make sure that image size must be 300*200
        if ($image_size[0] != 300 || $image_size[1] != 200)
            throw new Exception("图片尺寸必须是300*200");

        if ($data['type'] == "large_picture") {  // Generate large image with box


            // Draw the square with shadow
            $i = 17;
            while ($i < 127) {
                imagerectangle($img, $position_x_1, $position_y_1, $position_x_2, $position_y_2, imagecolorallocatealpha($img, 255, 255, 255, $i));
                $position_x_1 = $position_x_1 + 1;
                $position_y_1 = $position_y_1 + 1;
                $position_x_2 = $position_x_2 - 1;
                $position_y_2 = $position_y_2 - 1;
                $i = $i + 10;
            }


            // Set header in type jpg
            header("Content-type: image/jpg");

            // Generate image
            imagejpeg($img);

            // Release memory
            imagedestroy($img);

        }else if($data['type'] == "small_picture"){ // Generate small image

            // Create a small image with height 50 and width 50
            $img_small = imagecreatetruecolor(50,50);

            // Copy one part of the large image (the image with size 300*200) to small part of image
            imagecopy($img_small,$img,0,0,$position_x_1,$position_y_1,50,50);

            // Change brightness of the picture
            imagefilter($img_small, IMG_FILTER_BRIGHTNESS, 1000);

            $position_1= 0;
            $position_2 = 50;

            // Adding some blur in to small picture
            for ($i = 50; $i < 120; $i = $i + 6) {
                imagerectangle($img_small, $position_1, $position_1, $position_2, $position_2, imagecolorallocatealpha($img_small, 255, 255, 255, $i));
                $position_1 = $position_1 + 1;
                $position_2 = $position_2 - 1;
            }

            // Set header in type jpg
            header("Content-type: image/jpg");

            // Generate image
            imagejpeg($img_small);

            // Release memory
            imagedestroy($img_small);
            imagedestroy($img);
        } else if($data['type'] == "original_picture") {  // Generate original image
            // Set header in type jpg
            header("Content-type: image/jpg");

            // Generate image
            imagejpeg($img);

            // Release memory
            imagedestroy($img);
        } else {

            // If there is no parameter matched
            // Destroy the image
            imagedestroy($img);
            echo "Invalid parameters";
        }
    }

    public function toVerify( $data )
    {
        if( empty( $data['x'] ) || empty( $data['y'] ) )
            throw new Exception( '非法参数' );

        return $this->verify( $data['x'], $data['y'] );
    }
}

2,调用

<?php
/**
 * Created by PhpStorm.
 * User: lxd
 * Date: 2018/7/2
 * Time: 16:49
 */
namespace Partner\Controller;

use Common\Controller\PartnerbaseController;
use Partner\Logic\UserLogic;
use Partner\Logic\VerificationLogic;
use Think\Exception;
use Think\Log;
use Think\Think;
use translate\Translate;

class PublicController extends PartnerbaseController
{
    private $_verifyObjName     = 'tmpVerify';
    private $_verifyRes         = 'tmpVerifyRes';

    public function __construct()
    {
        if( APP_DEBUG )
            C('SHOW_PAGE_TRACE', false);
        parent::__construct();
        if( $this->getSessInfo( $this->userSessName ) )
            $this->redirect( 'index/index' );
    }

    /**
     * 初始化
     */
    public function index()
    {
        $this->_firstLogin();
        $this->display();
    }

    /**
     * 首次进入,依据ip设置语言信息
     */
    private function _firstLogin()
    {
        if( !$_SERVER['HTTP_REFERER'] && ( $this->getSessInfo( $this->lifeSessName, 'times' ) ) < 2 ) {
            Think::addMap( 'Iptolau', dirname( THINK_PATH ) . DIRECTORY_SEPARATOR . 'Lib' . DIRECTORY_SEPARATOR . 'Util' . DIRECTORY_SEPARATOR . 'Iptolau.class.php' );
            $ip2lau     = new \Iptolau();
            $lau        = $ip2lau->run( get_client_ip(0, true) );
            if( $lau )
                $this->_initLauguage( $lau, true );
        }
    }

    /**
     * 登陆
     */
    public function login()
    {
        $this->checkReferer();

        try {
            if( !$this->getSessInfo( $this->_verifyRes ) )
                throw new Exception( '非法操作' );

            $model      = new UserLogic();
            $res        = $model->getUserAuthor( I('post.') );
            $this->setSessInfo( $this->userSessName, $res['user'] );
            $this->setSessInfo( $this->menuSessName, $res['menu'] );
            $this->redirect( 'index/index' );
        }catch ( Exception $e ) {
            $this->error( $e->getMessage() );
        }
    }

    public function initVerify()
    {
        $obj    = new VerificationLogic();
        $this->setSessInfo( $this->_verifyObjName, $obj );
        $this->setSessInfo( $this->_verifyRes, false );
    }

    public function getImage()
    {
        try{
            $obj    = $this->getSessInfo( $this->_verifyObjName );
            $obj->getImage( I('get.') );
        }catch ( Exception $e ) {
            $this->error( $e->getMessage() );
        }
    }

    public function verify()
    {
        if( $this->getSessInfo( $this->_verifyRes ) || $this->getSessInfo( $this->userSessName ) )
            echo 0;

        try{
            $obj    = $this->getSessInfo( $this->_verifyObjName );
            if( $obj->toVerify( I('get.') ) ) {
                $this->setSessInfo( $this->_verifyRes, true );
                echo 1;
            }else {
                $this->setSessInfo( $this->_verifyRes, false );
                echo 0;
            }
        }catch ( Exception $e ) {
            $this->error( $e->getMessage() );
        }
    }
}

3,将js的调用路径改正

4,问题。

· 

验证的请求是这样,容易被刷。需要做ip,次数校验

 

posted @ 2018-08-22 10:09  栋的博客  阅读(462)  评论(0编辑  收藏  举报
深入理解php php扩展开发 docker mongodb