WordPress用户注册加上图片验证码

国内使用 wordpress 系统建站的已经非常普遍,但是我们都知道现在的垃圾注册信息非常猖獗,只要你开启了网站注册功能,马上会有机器人疯狂注册烦死你,为了网站安全,现在很多网站都在用户登录后台时添加了一个验证码验证,只有通过了验证码这一关,而后才进行用户验证。从体验上来讲,其实我是不想加验证码的,因为这会增加用户的操作,但有时候没有办法,为了防止机器人恶意注册,所以今天我来说一下如何给 WordPress 的前台注册加上验证码功能,很多方法都是要手动写验证码信息的,而且是固定验证码一点都不方便,今天 2 我们分享图片验证码方法,在安全系数上图片形式的验证码会更高一些。

方法一

将以下代码扔到主题模板函数 (functions.php)即可:

  1.     //WordPress新用户注册随机数学验证码
  2.     function add_security_question_fields() {
  3.     //获取两个随机数, 范围0~9
  4.     $num1=rand(0,9);
  5.     $num2=rand(0,9);
  6.     //最终网页中的具体内容
  7.     echo "<p><label for='math' class='small'>验证码:$num1 + $num2 = ? </label><input type='text' name='sum' class='input' value='' size='25'>"
  8.     ."<input type='hidden' name='num1' value='$num1'>"
  9.     ."<input type='hidden' name='num2' value='$num2'></p>";}
  10.     add_action('register_form','add_security_question_fields');
  11.     add_action( 'register_post', 'add_security_question_validate', 10, 3 );
  12.     function add_security_question_validate( $sanitized_user_login, $user_email, $errors) {
  13.     $sum=$_POST['sum'];//用户提交的计算结果
  14.     switch($sum){
  15.     //得到正确的计算结果则直接跳出
  16.     case $_POST['num1']+$_POST['num2']:break;
  17.     //未填写结果时的错误讯息
  18.     case null:wp_die('错误:请输入验证码!');break;
  19.     //计算错误时的错误讯息
  20.     default:wp_die('错误:验证码错误,请重试!');}}
  21.     add_action( 'add_security_question','register_form' );


此方法只适合使用 WordPress 默认注册页面,如果希望在用户登录页面也添加验证码,将以下代码扔到主题模板函数文件 (functions.php)即可:

  1.     //WordPress后台登陆随机数学验证码
  2.     function myplugin_add_login_fields() {
  3.     //获取两个随机数, 范围0~9
  4.     $num1=rand(0,9);
  5.     $num2=rand(0,9);
  6.     //最终网页中的具体内容
  7.     echo "<p><label for='math' class='small'>验证码:$num1 + $num2 = ? </label><input type='text' name='sum' class='input' value='' size='25'>"
  8.     ."<input type='hidden' name='num1' value='$num1'>"
  9.     ."<input type='hidden' name='num2' value='$num2'></p>";}
  10.     add_action('login_form','myplugin_add_login_fields');
  11.     function login_val() {
  12.     $sum=$_POST['sum'];//用户提交的计算结果
  13.     switch($sum){
  14.     //得到正确的计算结果则直接跳出
  15.     case $_POST['num1']+$_POST['num2']:break;
  16.     //未填写结果时的错误讯息
  17.     case null:wp_die('错误:请输入验证码!');break;
  18.     //计算错误时的错误讯息
  19.     default:wp_die('错误:验证码错误,请重试!');}}
  20.     add_action('login_form_login','login_val');

方法二

1、在主题目录下,新建一个目录及 PHP 文件,如:/inc/captcha.php;加入生成验证码的代码:

  1. <?php
  2.     require_once(dirname(__FILE__)."/../../../../wp-load.php"); // 目录结构,如果是按照我这种目录的话则不用修改
  3.     $font = get_template_directory()."/fonts/consolas-webfont.ttf"; // 引入验证码的字体文件,后面给出下载地址
  4.     class Imagecode{
  5.         private $width ;
  6.         private $height;
  7.         private $counts;
  8.         private $distrubcode;
  9.         private $fonturl;
  10.         private $session;
  11.         function __construct($width = 120,$height = 30,$counts = 5,$distrubcode="1235467890qwertyuipkjhgfdaszxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM",$fonturl){
  12.             $this->width=$width;
  13.             $this->height=$height;
  14.             $this->counts=$counts;
  15.             $this->distrubcode=empty($distrubcode)?"1235467890qwertyuipkjhgfdaszxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM":$distrubcode;
  16.             $this->fonturl=$fonturl;
  17.             $this->session=$this->sessioncode();
  18.             session_start();
  19.             $_SESSION['um_captcha']=$this->session;
  20.         }
  21.  
  22.          function imageout(){
  23.             $im=$this->createimagesource();
  24.             $this->setbackgroundcolor($im);
  25.             $this->set_code($im);
  26.             $this->setdistrubecode($im);
  27.             ImageGIF($im);
  28.             ImageDestroy($im); 
  29.         }
  30.  
  31.         private function createimagesource(){
  32.             return imagecreate($this->width,$this->height);
  33.         }
  34.         private function setbackgroundcolor($im){
  35.             $bgcolor = ImageColorAllocate($im, rand(200,255),rand(200,255),rand(200,255));
  36.             imagefill($im,0,0,$bgcolor);
  37.         }
  38.         private function setdistrubecode($im){
  39.             $count_h=$this->height;
  40.             $cou=floor($count_h*2);
  41.             for($i=0;$i<$cou;$i++){
  42.                 $x=rand(0,$this->width);
  43.                 $y=rand(0,$this->height);
  44.                 $jiaodu=rand(0,360);
  45.                 $fontsize=rand(4,6);
  46.                 $fonturl=$this->fonturl;
  47.                 $originalcode = $this->distrubcode;
  48.                 $countdistrub = strlen($originalcode);
  49.                 $dscode = $originalcode[rand(0,$countdistrub-1)];
  50.                 $color = ImageColorAllocate($im, rand(40,140),rand(40,140),rand(40,140));
  51.                 imagettftext($im,$fontsize,$jiaodu,$x,$y,$color,$fonturl,$dscode);
  52.             }
  53.         }
  54.         private function set_code($im){
  55.             $width=$this->width;
  56.             $counts=$this->counts;
  57.             $height=$this->height;
  58.             $scode=$this->session;
  59.             $y=floor($height/2)+floor($height/4);
  60.             $fontsize=rand(20,25);
  61.             $fonturl=$this->fonturl;
  62.  
  63.             $counts=$this->counts;
  64.             for($i=0;$i<$counts;$i++){
  65.                 $char=$scode[$i];
  66.                 $x=floor($width/$counts)*$i+8;
  67.                 $jiaodu=rand(-20,30);
  68.                 $color = ImageColorAllocate($im,rand(0,50),rand(50,100),rand(100,140));
  69.                 imagettftext($im,$fontsize,$jiaodu,$x,$y,$color,$fonturl,$char);
  70.             }
  71.  
  72.         }
  73.         private function sessioncode(){
  74.             $originalcode = $this->distrubcode;
  75.             $countdistrub = strlen($originalcode);
  76.             $_dscode = "";
  77.             $counts=$this->counts;
  78.             for($j=0;$j<$counts;$j++){
  79.                 $dscode = $originalcode[rand(0,$countdistrub-1)];
  80.                 $_dscode.=$dscode;
  81.             }
  82.             return $_dscode;
  83.         }
  84.     }
  85.     Header("Content-type: image/GIF");
  86.     $imagecode=new  Imagecode(90,39,4,'',$font);
  87.     $imagecode->imageout();

2、在前台注册的弹出层中加入 DOM 结构:

  1. <p id="captcha_inline">
  2.  
  3.     <input class="input-control inline" type="text" id="um_captcha" name="um_captcha" placeholder="输入验证码" required>
  4.  
  5.     <img src="<?php echo get_bloginfo('template_url'). '/inc/captcha.php'; ?>" class="captcha_img inline" alt="验证码" title="点击刷新验证码">
  6.     <input type="hidden" value="<?php echo get_bloginfo('template_url'); ?>" id="tplUrl">
  7.  
  8. </p>

3、在 functions.php 中加入下列代码,用于 ajax 请求用:

  1. // AJAX注册验证
  2. function hbao_ajax_register(){
  3. $result= array();
  4. if(isset($_POST['security']) && wp_verify_nonce( $_POST['security'], 'user_security_nonce' ) ){
  5. $user_login = sanitize_user($_POST['username']);
  6. $user_pass = $_POST['password'];
  7. $user_email = apply_filters( 'user_registration_email', $_POST['email'] );
  8. $captcha = strtolower(trim($_POST['um_captcha']));
  9. session_start();
  10. $session_captcha = strtolower($_SESSION['um_captcha']);
  11. $errors= new WP_Error();
  12. if( ! validate_username( $user_login ) ){
  13. $errors->add( 'invalid_username', __( '请输入一个有效用户名','hbao' ) );
  14. }elseif(username_exists( $user_login )){
  15. $errors->add( 'username_exists', __( '此用户名已被注册','hbao' ) );
  16. }elseif(email_exists( $user_email )){
  17. $errors->add( 'email_exists', __( '此邮箱已被注册','hbao' ) );
  18. }
  19.  
  20. do_action( 'register_post', $user_login, $user_email, $errors );
  21. $errors = apply_filters( 'registration_errors', $errors, $user_login, $user_email );
  22. if ( $errors->get_error_code() ){
  23. $result['success']= 0;
  24. $result['message'] = $errors->get_error_message();
  25.  
  26. } else {
  27. $user_id = wp_create_user( $user_login, $user_pass, $user_email );
  28. if ( ! $user_id ) {
  29. $errors->add( 'registerfail', sprintf( __( '抱歉,无法注册,请联系管理员','hbao' ), get_option( 'admin_email' ) ) );
  30. $result['success']= 0;
  31. $result['message'] = $errors->get_error_message();
  32. } else{
  33. update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag.
  34. wp_new_user_notification( $user_id, $user_pass );
  35. $result['success']= 1;
  36. $result['message']= esc_html__( '注册成功,即将为你自动登录','hbao' );
  37. // 自动登录
  38. wp_set_current_user($user_id);
  39.   wp_set_auth_cookie($user_id);
  40.   $result['loggedin']= 1;
  41. }
  42. }
  43. }else{
  44. $result['message'] = __('安全认证失败,请重试!','hbao');
  45. }
  46. header( 'content-type: application/json; charset=utf-8' );
  47. echo json_encode( $result );
  48. exit;
  49. }
  50. add_action( 'wp_ajax_ajaxregister', 'hbao_ajax_register' );
  51. add_action( 'wp_ajax_nopriv_ajaxregister', 'hbao_ajax_register' );
  52.  
  53. //~ 验证码 - 验证
  54. function um_add_register_captcha_verify($sanitized_user_login,$user_email,$errors){
  55. if(!isset($_POST['um_captcha'])||empty($_POST['um_captcha'])){
  56. return $errors->add( 'empty_captcha', __( '请填写验证码','hbao' ) );
  57. }else{
  58. $captcha = strtolower(trim($_POST['um_captcha']));
  59. session_start();
  60. $session_captcha = strtolower($_SESSION['um_captcha']);
  61. if($captcha!=$session_captcha){
  62. return $errors->add( 'wrong_captcha', __( '验证码错误','hbao' ) );
  63. }
  64. }
  65. }
  66. add_action('register_post','um_add_register_captcha_verify',10,3);

以上代码加好之后,请对照代码,看好里面 post 的一些字段,比如:security ,如果没有自己在 form 中加一下:

  1. <input type="hidden" id="user_security" name="user_security" value="<?php echo wp_create_nonce( 'user_security_nonce' );?>">

还有 hbao_ajax_register()我给出的代码是完整版的验证,所以你只要拿其中验证码的部分,即下面这段:

  1. $captcha = strtolower(trim($_POST['um_captcha']));
  2. session_start();
  3. $session_captcha = strtolower($_SESSION['um_captcha']);

在主题的 js 文件里加入下列代码,用于刷新验证码:

  1. // Refresh captcha
  2. $('img.captcha_img').on('click',function(){
  3.   var captcha = $('#tplUrl').val()+'/inc/captcha.php?'+Math.random();
  4.   $(this).attr('src',captcha);
  5. });

这里还有一个步骤我就不写了,就是验证码输入的正确错误判断,因为每个主题使用的方式不一样,我这边是 ajax 验证,所以都是通过 js 验证是否输入验证码,和输入的验证码是否正确。上面也给出了 PHP 的验证,可以参考使用(左侧侧边栏有本文涉及到的验证码字体文件下载地址)。

方法三

在你的 wordpress 主题的登录页面上添加如下代码:

  1. 输入验证码:<input type="text"><img src="checkcode.php" onclick="this.src='checkcode.php?code='+Math.random()">

然后,再创建一个 checkcode.php 文件,这个文件就是验证码生成文件,代码如下:

  1.     //创建一个验证码
  2.     $checkcode="";
  3.     for($i=0; $i<4; $i++){
  4.     $checkcode.=dechex(rand(1,15));
  5.     }
  6.  
  7.     //创建一个图片
  8.     $im = imagecreatetruecolor(130,30);//创建画布
  9.     $red = imagecolorallocate($im,255,255,255); //创建字体颜色
  10.  
  11.     //绘制干扰线
  12.     for($i=1; $i<20; $i++){
  13.     imagearc($im,rand(0,100),rand(0,20),rand(0,100),rand(0,20),rand(180,360),rand(0,180),imagecolorallocate($im,rand(0,255),rand(0,255),rand(0,255)));
  14.     }
  15.     //把数字验证码转换成图片
  16.     imagestring($im,rand(1,5),rand(0,100),rand(0,20),$checkcode,$red);
  17.  
  18.     //输出图片
  19.     header("content-type:image/jpg");
  20.     imagejpeg($im);
  21.  
  22.     //关闭资源
  23.     imagedestroy($im);

上面代码中,绘制干扰线下的 for 代码,会随机绘制 20 条弧线,并且大小、位置、弧度、颜色都是随机产生,每点击一次就会更换一次,这就增加了软件识别的难度。“//把数字验证码转换成图片”下面的代码也是随机的,并且每点击一次,验证码的位置和大小都会变化。

通过上面的代码,我们就简单地实现了登录验证码,如果你的 wordpress 登录也想用验证码技术,可以试一下这段验证码,如果想达到验证效果,如:只有验证码正确,才再去验证用户名和密码,这时,我们就只需要在上面的代码中添加 session 来保存这个验证码,然后再把你输入的验证码与 session 里保存的验证码一对比,就可以了。

总结

以上就是我们经常使用的 WordPress 网站注册加上图片验证码功能的几种方式,我们通常使用第 2 种,第一种好像只对 WordPress 默认注册登录页面有效,但是现在基本都使用主题自带的注册登录页面,如果还有什么疑问或者建议,欢迎多多交流,原创文章,文笔有限,文中若有不正之处,万望告知。

© 版权声明
THE END
喜欢就支持以下吧
点赞0赞赏
分享
相关推荐
  • 暂无相关文章
评论 抢沙发