首页 > 编程语言 >PHP微信扫码登录

PHP微信扫码登录

时间:2023-09-21 11:44:25浏览次数:175  
标签:扫码 微信 二维码 scene access token ticket PHP id

微信扫码登录总体说明:先获取token和ticket,通过微信生成二维码接口生成二维码,把二维码信息添加到数据表中,用户扫码时检测二维码扫描状态,扫描成功后更新二维码状态,跳转页面。 

微信开放文档

一、数据表

qrcord表,用户存储二维码信息,每生成一个二维码生成一条记录,通过openid字段判断是否扫描成功,如果openid不为空说明扫描成功,否则扫描失败或者是一条新的二维码,id字段就是下面使用的scene_id,此字段一直存在,作为操作二维码的关键字段。

id    addtime    openid    createtime    updatetime
ID    二维码生成时间    微信id    创建时间    更新时间

二、获取token

逻辑说明:请求微信接口获取token,把获取到token存储到服务器上,并把当前时间一并存储,用于判定token是否失效(因为token是有失效时间的),在调用此方法的时候,把当前时间和token数据库存储的时间(就是获取token的时间)对比,如果当前时间 > 数据库存储时间+7000,单位是秒,说明原来的token已经失效了,需要再重新获取token,并把新的存储到数据库中。

public function access_token()
{
  $time = time();
  $access_token = db::table('access_token')->find();
  $up_time = $access_token['update_time']+7000;
  if($time < $up_time){
    return $access_token;
  }else{
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".AppID."&secret=".AppSecret;
    // $access_token =  http_curl($url,'get');
    $access_token =  http_get_json($url);
    $save['update_time'] = time();
    $save['access_token'] = $access_token['access_token'];
    db::table('access_token')->where('id',1)->update($save);
    return $access_token;
  }
  
}

三、生成二维码
逻辑说明:① 在生成二维码前,首先生成一条数据插入qrcode表,用于记录二维码状态,数据包括二维码生成时间,插入后返回自增主键ID,把返回的ID赋给变量$scene_id,② 开始生成二维码:拼凑参数:二维码有效时间、二维码类型、二维码详细信息,拼接URL,请求(两个)微信接口生成二维码。

public function qrcode()
{
    //先删除openid为空的垃圾数据 
	Db::table('qrcode')->where(['openid'=>''])->delete();
    //插入数据 - 二维码记录
    $data_insert = [
        'addtime'=>  time(),
    ];
        
    // 插入新记录,并返回记录id
    $scene_id = Db::table('qrcode')->insertGetId($data_insert); 
        
    if(!$scene_id){
      	return false;
    }
    $token = $this->access_token();
    $access_token = $token['access_token'];
    $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
    // 参数
    $param = array();
    $param['expire_seconds'] = 3600 * 24; //有效时间 
    $param['action_name'] = 'QR_SCENE'; //二维码类型 
    $param['action_info']['scene']['scene_id'] = $scene_id;  //二维码详细信息
    $param = json_encode($param,true);
 
    // 返回二维码的ticket和二维码图片解析地址
    $ticket_arr = $this->http_curl($url, 'post', 'json', $param);
    //拿ticket换取二维码
    if (empty($ticket_arr['errcode'])) { 
        $ticket = $ticket_arr['ticket'];
       // 通过ticket换取二维码
       $qrcode = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".$ticket_arr['ticket'];
 
        $api = array();
        $api['qrcode'] = $qrcode;
        $api['scene_id'] = $scene_id;
        return $api;
            
    }else { 
      
       //echo '发生错误:错误代码 ' . $ticket_arr['errcode'] . ',微信返回错误信息:' . $ticket_arr['errmsg']; 
       //   return   apiResponse(110,$ticket_arr['errcode'],$ticket_arr['errmsg']);
       return '110';
    }
}

前端代码:用标签直接显示二维码,隐藏域为scene_id,用于查询二维码信息(包括二维码扫描状态)。

<img src="{$qrcode.qrcode}"  style="width: 250px;box-shadow:0 0 10px #F1F3F4">
<input type="hidden" name="scene_id" id="" value="{$qrcode.scene_id}" />

四、扫码,并接收回调
说明:生成二维码后,用户可以扫描二维码,如果扫描之后,微信服务器会收到,并返回信息,就是返回到事先填写在微信公众号上的回调地址,注意这个地址是可以公开访问的,不能有验证,否则微信服务器无法返回消息给回调地址。

回调方法处理逻辑:接收微信服务器返回的消息,返回的消息格式默认是xml,需要把它转换成对象格式,返回的信息包括EventKey,FormUserName,ToUserName,Event。根据scene_id修改qrcode表信息,主要是添加openid,表示该二维码已被用户扫码成功。

public function wxBack()
	{
		$postStr = file_get_contents('php://input'); // 获取请求体
     
	    //写入文件
	   // file_put_contents('./uploads/weixin.log', $postStr."\r\n", FILE_APPEND); // 将信息追加到文件末尾
	    $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
	    
	    $scene_id = $postObj->EventKey;
 
        $openid = $postObj->FromUserName;   //openid
          
        $ToUserName = $postObj->ToUserName;  //公众号
        
        $Event = strtolower($postObj->Event);   //事件类型
        
        //添加扫码记录
        $res = Db::table('qrcode')->where('id',$scene_id)->update(['openid'=>$openid,'createtime'=>time()]);
	}

五、检测二维码是否扫描成功
逻辑说明:使用函数每隔2秒执行一次查询一次二维码扫描状态,在后端通过scene_id查询qrcode表里的openid,如果对应的openid列为空,说明这是一个新的二维码,还没有用户扫描,如果对应的openid列不为空说明已经被扫描,扫码成功,那就推送消息并跳转页面。

前端代码 

// 每2秒查询一次数据表用户是否已经扫码
$(document).ready(function(){
   	c = setInterval(check_login,2000);   //每2秒执行一次
});
 
//检测用户是否已扫描
function check_login() { 
	    
        var scene_id=$("input[name='scene_id']").val();
 
        $.ajax({
            url:'check_login2',   //请求地址
            data:{scene_id:scene_id},   //发送的数据
            type:'POST',     //请求的方式
            dataType:'JSON',
            success:function(res){
                // console.log(res)
                if(res.code == '200'){  //已完成推送
                    layer.msg(res.message, {
                      icon: 1,
                      time: 2000 //2秒关闭(如果不配置,默认是3秒)
                    }, function(){
                      window.location.href='/teacher/index/index';
                    });
                    window.clearInterval(c); //终止
                }else if(res.code == '110'){
                    layer.msg(res.message, {
                      icon: 2,
                      time: 2000 //2秒关闭(如果不配置,默认是3秒)
                    })
                    
                    window.clearInterval(c); //终止
                    
                    setTimeout(function(){
                        window.location.reload();//刷新当前页面. 100s
                    },3000)
                    
                }
            }     
       })
}

后端代码

    public function check_login2(){
         if (request()->isPost()) {
             
             $scene_id = input('post.scene_id');
             // 获取二维码信息
	        $res = model('Login')->getQrcodeInfo($scene_id);
	        if (!empty($res['openid'])) {
	                
    				    //推送登录成功消息
    	               	$token = access_token();
    		            $access_token = $token['access_token'];
    		          //  微信推送
    	                $url="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token;
    	                
    	                $post_data = array(
    
                            "touser"=>$user['openid'], //推送给谁,openid
                
                            "template_id"=>"xxxxxx", //微信后台的模板信息id      
                
                            "data"=> array(
                                "first" => array(
                                    "value"=>"账号登录成功 - 首医中医药研学平台",
                                    "color"=>"#888"
                                ),
                                "keyword1"=>array(
                                    "value"=>$user['name'], //传的变量
                                    "color"=>"#888"
                                ),
                                 "keyword2"=>array(
                                    "value"=> date("Y.m.d H:i:s",time()),
                                    "color"=>"#888"
                                ), 
                                "keyword3"=>array(
                                    "value"=>'教师', //传的变量
                                    "color"=>"#888"
                                ),
                                "remark"=>array(
                                    "value"=> '您已成功登录!',
                                    "color"=>"#888"
                                ),  
                            )
                
                        );
                        //将上面的数组数据转为json格式
                        $post_data = json_encode($post_data);
                        
                        //发送数据,post方式
                        //配置curl请求
                        $ch = curl_init();
                        curl_setopt($ch,CURLOPT_URL,$url);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //设置有返回值,0,直接显示
                        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0); //禁用证书验证
                        curl_setopt($ch,CURLOPT_POST,1);
                        curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);
                    
                        //接收执行返回的数据
                        $res = curl_exec($ch);
                    
                        //关闭句柄
                        curl_close($ch);
                       
                        // return apiResponse('200','登录成功');
    					return apiResponse('200','登陆成功,正在跳转...');
    				}
	           
	            
	        }else{
	            return apiResponse('100','操作失败,请刷新页面重试!');
	        }
	        
         }else{
             return apiResponse('110','非法请求');
         }
     }

 

标签:扫码,微信,二维码,scene,access,token,ticket,PHP,id
From: https://www.cnblogs.com/guangzhiruijie/p/17719562.html

相关文章

  • 基于微信小程序的宠物店商城设计与实现
    宠物不仅可以陪伴也可以释放工作、生活中的压力。现如今人们养宠物的非常多,相对的需要宠物服务的也增多。去宠物店预约宠物服务需要自己腾出时间去亲自参与,非常不方便,不适应现代人的生活。想要了解服务详情、价格信息等都需要自己去实体店查找。商家对于相关信息的管理也没有有效的......
  • 基于微信小程序校园订餐的设计与开发
    人民生活水平的提高就会造成生活节奏越来越快,很多人吃饭都采用点外卖的方式。现在点外卖的平台已有很多,大多都需要安装它们的APP才可以使用,并且没有针对校园。如果一味的使用外卖平台不仅会造成商家成本的增加,还不利于商家校园订单的配送。开发基于微信小程序的校园订餐系统可以解......
  • php通过curl获取数据
    <?phpheader("Content-Type:text/html;charset=UTF-8");$url='https://www.baidu.com';print_r(curlContent($url));functioncurlContent($url,$method='get',$dataArr=array(),$headerArr=array()){$method=strtolower($......
  • 企业微信针对百万级组织架构的客户端性能优化实践
    本文由腾讯WXG客户端开发工程师yecong分享,本文做了修订和改动。1、引言相对于传统的消费级IM应用,企业级IM应用的特殊之外在于它的用户关系是按照所属企业的组织架构来关联的起来,而组织架构的大小是无法预设上限的,这也要求企业级IM应用在遇到真正的超大规模组织架构时,如何保证......
  • PHP多层级菜单树形结构递归处理
    如题:一、数据库菜单数据表使用图片中id和parent_id两个参数来关联父子关系二、将数据库中的数据变成树状多层级解构```{ "id":1, "parentId":0, "treePath":"0", "name":"系统管理", "type":2, "path":"/system",......
  • 【漏洞复现】深信服 SG上网优化管理系统 catjs.php 任意文件读取漏洞
    1、简介2、漏洞描述深信服SG上网优化管理系统catjs.php存在任意文件读取漏洞,攻击者通过漏洞可以获取服务器上的敏感文件3、受影响版本深信服SG上网优化管理系统4、FOFA语句title==“SANGFOR上网优化管理”5、漏洞复现POCPOST/php/catjs.phpHTTP/1.1Host:User-A......
  • 微信服务直达配置问题
     鲜花同城配送玫淳自从8月22号前夕花海上去了之后,节日后几天聚联订花又上去了,前后做了很多每天1000,2000都试过排名没任务相应现在想修改服务直达看看,下面是备份  ......
  • vx微信账号被限制了怎么办
    微信被限制了怎么解除限制一、账号为什么会限制登录一般出现以下情况均会被限制登录:干扰微信正常运营、侵犯其他用户或第三方合法权益,比如恶意添加其他用户、传播低俗信息等。在微信发表、使用不良信息,比如冒充国家机关和媒体发布虚假信息、传播是与他人不道德的信息等。用......
  • php实现大文件断点续传下载实例
    php实现大文件断点续传下载实例,看完你就知道超过100M以上的大文件如何断点传输了,这个功能还是比较经典实用的,毕竟大文件上传功能经常用得到。1require_once('download.class.php');2date_default_timezone_set('Asia/Shanghai');3error_reporting(E_STRICT);4......
  • phpstudy无法启动mysql(启动之后立马关闭)
    好久没有打开本地环境,直到昨天打开phpstudy,正常启动,但是在任务管理器中发现没有mysql服务于是在mysql的bin目录下执行.\mysqld.exe--install  mysql服务是有了,但这个问题就来了重启phpstudy无法启动mysql注意:在此之前注意备份mysql数据,查看现在设置的mysql密码,以便本地项......