自定义滑动验证码
来源: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,次数校验