千帆开发李奕飞 发表于 2017-9-27 15:00:23

【PHPWIND】PC实名认证

本帖最后由 千帆开发李奕飞 于 2017-9-27 15:40 编辑

根据国家相关政策,地方网站需要在10月后全面开启实名认证,要求所有会员必须绑定手机号。
化龙巷论坛在9月份开发完成,实现了发帖、回帖、评分时,验证是否绑定手机号,并弹窗引导用户实时绑定手机号。
千帆团队于9月份完成了DISCUZ站点实名认证插件。
鉴于PHPWIND站点特殊情况太多,实在没有标准,无法一概而论,所以在此附上了化龙巷实现该功能的流程,
请各大PHPWIND站点自行斟酌修改。

化龙巷手机相关表:

pw_members_mobile_book (手机实名表):
CREATE TABLE `pw_members_mobile_book` (
`uid` int(10) unsigned NOT NULL,
`username` varchar(40) NOT NULL DEFAULT '',
`mobile` varchar(11) NOT NULL,
`status` tinyint(3) unsigned NOT NULL DEFAULT '0',
`createdtime` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`),
KEY `index_mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
pw_sms_logs (短信发送日志表):
CREATE TABLE `pw_sms_logs` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`mobile` char(11) NOT NULL DEFAULT '' COMMENT '手机号',
`content` varchar(255) NOT NULL DEFAULT '' COMMENT '内容',
`sendtime` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_mobile` (`mobile`),
KEY `idx_mobile_sendtime` (`mobile`,`sendtime`)
) ENGINE=InnoDB AUTO_INCREMENT=662726 DEFAULT CHARSET=gbk;
pw_mobile_verifycode (动态验证码存放表):
CREATE TABLE `pw_mobile_verifycode` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(11) unsigned NOT NULL DEFAULT '0',
`mobile` varchar(12) NOT NULL DEFAULT '',
`verifycode` varchar(10) NOT NULL DEFAULT '',
`expire_at` int(10) unsigned NOT NULL DEFAULT '0',
`created_at` int(10) unsigned NOT NULL DEFAULT '0',
`updated_at` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_mobile_createdat` (`mobile`,`created_at`)
) ENGINE=MyISAM AUTO_INCREMENT=3275 DEFAULT CHARSET=gbk;


修改PHP文件
修改 ./require/common.php 增加对应函数:文件中的 $mobileBinded 会渲染给模板,在模板内判断发帖等按钮的对应交互
/**
* 手机号验证判断
* @return bool
*/
function mobileBinded($uid){
    global $db, $groupid;

    // 自己的马甲不验证手机
    if (in_array($groupid, array(80, 67))) {
      return true;
    }
    $mobile = $db->get_value("SELECT mobile FROM pw_members_mobile_book WHERE uid=" . S::sqlEscape($uid) . " LIMIT 1");

    return $mobile ? true : false;
}
该函数主要实现返回当前用户是否绑定了手机。

修改 ./thread.php 在头部增加以下逻辑(红色标注):<?php
define('SCR','thread');
require_once('global.php');

// 请将以下这段函数调用复制到文件中,其他不要
$mobileBinded = mobileBinded((int)$winduid);
修改 ./read.php<?php
define('SCR','read');
require_once('global.php');

// 请将以下这段函数调用复制到文件中,其他不要
$mobileBinded = mobileBinded((int)$winduid);

修改 ./require/postnew.php<?php
!function_exists('readover') && exit('Forbidden');

// 请将以下这段函数调用复制到文件中,其他不要
if (!mobileBinded($winduid)){
    Showmsg('请先<a href="http://i.hualongxiang.com/profile">绑定手机</a>');
}
修改 ./require/postreply.php
<?php
// 请将以下这段函数调用复制到文件中,其他不要
if (!mobileBinded($winduid)){
    Showmsg('请先<a href="http://i.hualongxiang.com/profile">绑定手机</a>');
}
修改模板文件、增加样式、JS文件

鉴于PW站点模板文件都不太一致,故在此以文件压缩包形式展现,请站点下载后自行查看。可在文件内搜索 "$mobileBinded"。请于文章结尾下载模板压缩包,自行参考。
注意:在read.htm 和 thread.htm 两个文件底部,需要增加弹框,压缩包的文件中已有,请参考。
<div class="pop-mobile">
                <div class="h_title">
                        <div class="txt">绑定手机</div>
                        <div class="closeds mclosed"></div>
                </div>
                <div class="bang-form-box">
                        <p class="mb20">应国家法规对账号实名的要求,<br />
                              进行下一步操作前,请先完成手机绑定。<a href="http://www.hualongxiang.com/read.php?tid=13599034" target="_blank">了解更多</a></p>
                        <form method="post" action="" class="clearfix mb20">
                              <div class="info-box">
                                        <div class="input-box div-phone"><i class="icon-tel"></i><input type="text" id="phone" class="long_txt" maxlength="11" placeholder="请输入手机号码" autocomplete="off" datatype="m" errormsg="手机号码格式不正确" nullmsg="请填写正确的手机号码" /></div>
                                        <a href="javascript:;" class="send1">发送验证码</a>

                              </div>
                              <div class="info-box">
                                        <div class="input-boxdiv-yzm"><i class="icon-yz"></i><input type="text" id="ranks" class="long_txt" maxlength="6" placeholder="请输入验证码"/></div>

                              </div>
                              <div class="info-box">
                                        <a href="javascript:;" class="conform">立即绑定</a>
                              </div>
                        </form>
                        <p>
                              验证出现问题?
                              <br>
                              您可以在线客服求助或拨打客服电话0519-86601957
                              <br>
                              想要找回绑定手机的账号?你可以<a href="http://www.hualongxiang.com/chazuo/13599034#147851057" target="_blank">戳这里</a>。
                        </p>
                </div>
                <div class="success-box dn">
                        <div class="icon-ok"></div>
                        <p>绑定成功</p>
                        <p id="btime"></p>
                </div>
      </div>
      <div class="markbg"></div>
部署AJAX后端绑定手机文件:

./bind_mobile_ajax.php
<?php
/**
* Created by PhpStorm.
* User: liyifei
* Email: 119422342@qq.com
* Date: 17-8-23
* Time: 下午4:12
*/

require_once "global.php";


$action = $_POST['action'];
if (!$winduid) {
    throw new Exception("illegal request");
}

$mobile = $_POST["mobile"];
// 验证手机号
if (!preg_match("/^1{9}$/", $mobile)) {
    echo json_encode(array(
      "status" => 1,
      "message" => "请填写正确的手机号",
      "target" => "phone"
    ));
    exit(0);
}
$uid = $db->get_value("SELECT uid FROM pw_members_mobile_book WHERE mobile=" . S::sqlEscape($mobile));
if ($uid) {
    echo json_encode(array(
      "status" => 1,
      "message" => "该手机号已经绑定了其他用户",
      "target" => "phone"
    ));
    exit(0);
}

$binded = $db->get_value("SELECT mobile FROM pw_members_mobile_book WHERE uid=" . S::sqlEscape($winduid));
if ($binded) {
    echo json_encode(array(
      "status" => 1,
      "message" => "您已经绑定了手机",
      "target" => "phone"
    ));
    exit(0);
}

switch ($action) {
    case "send":
      require_once(R_P . 'require/Mandao.php');

      //验证当天条数
      $start = strtotime(date('Y-m-d 00:00:00'));
      $end = time();

      $num = $db->get_value("SELECT count(*) FROM pw_sms_logs WHERE mobile = " . S::sqlEscape($mobile)
            . " AND sendtime between " . $start . " AND " . $end);
      if ($num >= 10) {
            echo json_encode(array(
                "status" => 1,
                "message" => "您当天发送次数过多",
                "target" => "phone"
            ));
            exit(0);
      }

      //验证省内手机号
      $url = "http://cx.shouji.360.cn/phonearea.php?number=" . $mobile;
      $content = curl_get_contents($url, 3);
      $content = json_decode($content, TRUE);
      if (isset($content['data']['province']) && $content['data']['province'] != '江苏') {
            echo json_encode(array(
                "status" => 1,
                "message" => "非江苏省内的手机号无法进行实名认证",
                "target" => "phone"
            ));
            exit(0);
      }

      // 生成验证码
      $yzm = rand(1000, 9999);

      // 发送短信
      $sdk = new Mandao(array(
            'serialNumber' => 'DXX-WSS-100-08208',
            'password' => '287532'
      ));
      $message = mb_convert_encoding('【化龙巷】您的验证码为:' . $yzm . ',切勿将验证码泄露给他人。', 'GBK', 'UTF-8');

      $result = $sdk->sendSms($mobile, $message);

      if ($result == 0) {
            // 入库
            pwQuery::insert("pw_mobile_verifycode", array(
                "uid" => $winduid,
                "mobile" => $mobile,
                "verifycode" => $yzm,
                "expire_at" => $timestamp + 3600,
                "created_at" => $timestamp,
                "updated_at" => 0
            ));
            pwQuery::insert("pw_sms_logs", array(
                "mobile" => $mobile,
                "content" => $message,
                "sendtime" => $timestamp
            ));
      }

      echo json_encode(array(
            'status' => 0,
            'message' => ''
      ));
      exit(0);
      break;
    case "bind":
      $verifycode = $_POST['yzm'];
      $log = $db->get_one("SELECT * FROM pw_mobile_verifycode WHERE mobile=" . S::sqlEscape($mobile) . " ORDER BY created_at DESC LIMIT 1");
      // 验证码是否正切
      if ($log['verifycode'] != $verifycode) {
            echo json_encode(array(
                "status" => 1,
                "message" => "验证码不正确",
                "target" => "yzm"
            ));
            exit(0);
      }

      // 验证码是否过期
      if ($log['expire_at'] - $timestamp > 3600) {
            echo json_encode(array(
                "status" => 1,
                "message" => "验证码已过期,请重新发送",
                "target" => "yzm"
            ));
            exit(0);
      }

      // 是否是同一个用户
      if ($log['uid'] != $winduid) {
            echo json_encode(array(
                "status" => 1,
                "message" => "非法请求"
            ));
            exit(0);
      }

      // 入库
      $uid = $db->get_one("SELECT uid FROM pw_members_mobile_book WHERE uid = " . S::sqlEscape($winduid));
      if ($uid) {
            $db->update("UPDATE pw_members_mobile_book SET mobile = " . S::sqlEscape($mobile) . " WHERE uid=" . S::sqlEscape($winduid));
      } else {
            pwQuery::insert("pw_members_mobile_book", array(
                "uid" => $winduid,
                "username" => $windid,
                "mobile" => $mobile,
                "status" => 1,
                "createdtime" => $timestamp
            ));
      }


      // 删除验证码
      pwQuery::delete('pw_mobile_verifycode', 'mobile=:mobile', array($mobile));


      echo json_encode(array(
            'status' => 0,
            'message' => ''
      ));
      exit(0);
    default:
      break;
}




vdffdgfu 发表于 2017-10-9 10:30:08

明白了解
页: [1]
查看完整版本: 【PHPWIND】PC实名认证