自动通过邮箱连接修改密码

时间:2022-09-09 16:02:26

做了一个加速器账号出租的项目,按小时收费往外租加速器账号,时间到了之后,系统自动修改加速器的密码

修改密码需要进入绑定的邮箱,点击修改密码的链接,然后在新页面中提交新密码,这一切都需要后台自动完成

将过期的账号放到一个消息队列中,然后一个一个修改,修改出错的标记上,提醒人工修改

下面通过后台管理页面每20秒左右访问这个接口,从消息队列中读取待修改的账    

      public function change_pwd_GET(){ 
//取出一个未处理的号 $where_2['state ='] = 0; //未处理 $res = $this->sql('other.jiasu_change_pwd')->select()->where($where_2)->limit(1)->query(); if(count($res) == 0){ out('{"rt":200,"msg":"没有到期账号"}'); return; }
     //找回密码的界面,填入自己的邮箱
$rt = curl_do('http://www.XXXXX.com/user.php',['email' => $res[0]['email'],'act' => 'send_pwd_email'],'POST',['header' => [USER_AGENT]]); //邮件发送出错 if(!strpos($rt[1],'code":0')){ //将队列中的状态改为1,表明自动修改失败 out('{"rt":300,"msg":"邮件发送出错"}'); return; } sleep(4);//等待邮件发送成功 //读取邮件中的信息,并从邮件中提取出添加新密码的链接 $href = jsHrefGet($res[0]['email'],$res[0]['emailpwd']); if($href == false){ out('{"rt":300,"msg":"邮件读取失败"}'); return; } if($href !== false){ $rt = curl_do($href,'','GET',['need_header' => true,'header' => [USER_AGENT]]); if($rt[0] === 302){ preg_match('/Location: (.+)\r\n/U',$rt[1],$Location); if(isset($Location[1])){ $rt = curl_do($Location[1],'','GET',['need_header' => true,'header' => [USER_AGENT]]); if($rt[0] === 200){ if(strpos($rt[1],'无效链接') === false){ preg_match('/name="code" value="(.+)"/U',$rt[1],$code); if(isset($code[1])){ $cookies = curl_cookie($rt[1]); $new_password = rand_pwdd(); $rt = curl_do('http://www.XXXXX.com/user.php','new_password='.$new_password.'&target=&confirm_password='.$new_password.'&act=act_edit_password&uid=&code='.$code[1].'&Submit=%E6%8F%90%E4%BA%A4','POST',['cookie' => $cookies,'header' => [USER_AGENT]]); if($rt[0] === 200 && strpos($rt[1],'您的密码已修改成功,请牢记!') !== false){ // todo... 修改数据库中的密码和重新上架出租 out('{"rt":0,"msg":"Success"}'); }else{ //将队列中的状态改为3,表明自动修改失败 out('{"rt":101,"msg":"修改密码出错"}'); return; } } }else{ //将队列中的状态改为3,表明自动修改失败 out('{"rt":101,"msg":"链接失效"}'); return; } } } } } die(); }



用到的两个函数

   function jsHrefGet($mail,$pwd){

    if(strpos($mail,'@sina.com') !== false){
        $imap = imap_open('{imap.sina.cn:993/ssl}INBOX',$mail,$pwd);
    }else{
        $imap = imap_open('{imap.qq.com:993/ssl}INBOX',$mail,$pwd);
    }
    $mail_num = imap_num_msg($imap);
    for($i = $mail_num;$i > 0;-- $i){
        $header = imap_header($imap,$i);
        if(isset($header->to[0])){
            $from = $header->from[0]->mailbox.'@'.$header->from[0]->host;
            $to = $header->to[0]->mailbox.'@'.$header->to[0]->host;
            $body = imap_qprint(imap_fetchbody($imap,$i,1));
            $body = strtr($body,['  ' => '','    ' => '',"\r\n" => '',"\n" => '']);
            //print($body);
              preg_match('/新密码重置操作!<ahref="(.+)">http:\/\/www.XXXXXX.com\/\//U',$body,$href);
            //preg_match('/新密码重置操作!<ahref="(.+)" /U',$body,$href);
            //var_dump($href);
            if(isset($href[1])){
                if($from === 'account@service.htjsq.com' && $to == $mail){
                    return $href[1];
                }
            }
        }
    }

    return false;
}


    function rand_pwdd(){

        $str = 'abcdefghijkmnpqrstuvwxyz23456789';
        $strLen = strlen($str) - 1;

        $randStr = '';
        for($i = 0;$i < 8;++ $i){
            $randStr .= $str[mt_rand(0,$strLen)];
        }
        return $randStr;
    }

每个项目的页面都是不一样的,正则的写法也不一样,主要体会读取邮件(需要开通IMAP),curl操作的学习

 

curl_do的自动封装

 

/**
* curl_do
**/
function curl_do($url,$data = '',$method = 'GET',$param = []){    // 通过curl请求一个url,data为k=v&k1=v1的格式(数组时自动整理)或post一个xml数据
    // 如果使用证书则在$cert参数传入包含证书cert.pem和私钥key.pem的文件夹路径

    if(!isset($param['cookie'])){ $param['cookie'] = false; }
    if(!isset($param['header'])){ $param['header'] = false; }
    if(!isset($param['timeout'])){ $param['timeout'] = 10; }
    if(!isset($param['need_header'])){ $param['need_header'] = false; }
    if(!isset($param['cert'])){ $param['cert'] = false; }

    $ch = curl_init();
    switch($method){
        case 'GET':
            if(is_array($data)){
                $data_str = '';
                if(count($data) !== 0){
                    foreach($data as $k => $v){
                        $data_str .= '&'.$k.'='.urlencode($v);
                    }
                    $data_str = substr($data_str,1);
                }
            }else{
                $data_str = &$data;
            }
            curl_setopt($ch,CURLOPT_URL,$url.($data_str === '' ? '' : '?'.$data_str));
        break;
        case 'POST':
            curl_setopt($ch,CURLOPT_URL,$url);
            curl_setopt($ch,CURLOPT_POST,true);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
        break;
        case 'PUT':
        case 'DELETE':
            curl_setopt($ch,CURLOPT_URL,$url);
            curl_setopt($ch,CURLOPT_CUSTOMREQUEST,$method);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
        break;
    }

    if($param['cert'] !== false){    // 如果使用证书
        // 证书和证书路径
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLCERT,$param['cert'].'cert.pem');
        // 私钥和私钥路径
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLKEY,$param['cert'].'key.pem');
    }

    if(substr($url,0,5) === 'https'){    // 如果是ssl安全请求
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    }

    // 如果设置cookie
    if($param['cookie'] !== false){
        if(is_array($param['cookie'])){
            $cookie_str = '';
            if(count($param['cookie']) !== 0){
                foreach($param['cookie'] as $k => $v){
                    $cookie_str .= '; '.$k.'='.$v;
                }
                $cookie_str = substr($cookie_str,2);
            }
            $param['cookie'] = $cookie_str;
        }
        curl_setopt($ch,CURLOPT_COOKIE,$param['cookie']);
    }

    // 如果设置header
    if($param['header'] !== false){
        curl_setopt($ch,CURLOPT_HTTPHEADER,$param['header']);
    }

    curl_setopt($ch,CURLOPT_HEADER,$param['need_header']); // 将头文件的信息作为数据流输出
    curl_setopt($ch,CURLOPT_TIMEOUT,$param['timeout']);
    curl_setopt($ch,CURLOPT_ENCODING,'');
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);    // 要求结果为字符串且输出到屏幕
    
    $rt = [];
    $rt[1] = curl_exec($ch);
    $rt[0] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
    $rt[2] = $url;
    $rt[3] = $method;
    $rt[4] = $data;
    $rt[5] = curl_errno($ch);
    curl_close($ch);
    return $rt;
}