[Desarrollo PHP + WeChat] Inicio de sesión con código de escaneo WeChat

Tabla de contenido

1. tabla de datos

2. Obtener ficha

3. Generar código QR

4. Escanea el código y recibe la devolución de llamada

5. Compruebe si el código QR se escaneó correctamente.


Instrucciones generales para iniciar sesión con el código de escaneo de WeChat: primero obtenga el token y el boleto, genere el código QR a través de la interfaz de generación de códigos QR de WeChat, agregue la información del código QR a la tabla de datos y detecte el estado de escaneo del código QR cuando el usuario escanea el código Después de que el escaneo sea exitoso, actualice el estado del código QR y salte a la página.

Referencia relacionada: Plantilla de mensaje de WeChat push + php para el desarrollo de WeChat

El desarrollo PHP WeChat genera un código QR y escanea el código para seguir la cuenta oficial de WeChat

 Documento abierto de WeChat

1. tabla de datos

tabla qrcord, el usuario almacena información del código QR. Cada vez que se genera un código QR, se genera un registro. El campo openid se utiliza para determinar si el escaneo es exitoso. Si el openid no está vacío, el escaneo es exitoso. De lo contrario, el escaneo falla o es un nuevo código QR, id. El campo es scene_id que se usa a continuación. Este campo siempre existe como un campo clave para operar códigos QR.

identificación agregar tiempo identificador abierto crear tiempo tiempo de actualizacion
IDENTIFICACIÓN Tiempo de generación del código QR Identificación WeChat tiempo de creación Tiempo de actualizacion

2. Obtener ficha

Descripción lógica: solicite la interfaz WeChat para obtener el token, almacene el token obtenido en el servidor y almacene la hora actual juntos para determinar si el token ha caducado (porque el token tiene un tiempo de caducidad). Al llamar a este método, compare el hora actual con la hora almacenada en la base de datos del token (es decir, la hora en la que se obtuvo el token). Si la hora actual > tiempo de almacenamiento de la base de datos + 7000, la unidad es segundos, significa que el token original ha caducado y usted Necesita obtener el token nuevamente y almacenar el nuevo en la base de datos.

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;
  }
  
}

3. Generar código QR

Descripción lógica: ① Antes de generar el código QR, primero genere un dato e insértelo en la tabla qrcode para registrar el estado del código QR. Los datos incluyen el tiempo de generación del código QR. Después de la inserción, la ID de clave primaria que aumenta automáticamente se devuelve y el ID devuelto se asigna a la variable $scene_id, ② Comience a generar el código QR: junte los parámetros: tiempo de validez del código QR, tipo de código QR, detalles del código QR, URL de empalme, solicitud (dos) de interfaces WeChat para generar Código QR.

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';
    }
}

Código de interfaz: use etiquetas para mostrar directamente el código QR. El campo oculto es scene_id, que se utiliza para consultar la información del código QR (incluido el estado de escaneo del código QR).

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

4. Escanea el código y recibe la devolución de llamada

Nota: Después de generar el código QR, el usuario puede escanear el código QR. Si se escanea, el servidor WeChat lo recibirá y devolverá la información, que debe regresar a la dirección de devolución de llamada previamente ingresada en la cuenta oficial de WeChat. Tenga en cuenta que esta dirección es de acceso público. Sí, no puede haber verificación; de lo contrario, el servidor WeChat no puede devolver el mensaje a la dirección de devolución de llamada.

Lógica de procesamiento del método de devolución de llamada: reciba el mensaje devuelto por el servidor WeChat. El formato del mensaje devuelto es xml de forma predeterminada. Debe convertirse al formato de objeto. La información devuelta incluye EventKey, FormUserName, ToUserName y Event. Modifique la información de la tabla QRcode según scene_id, principalmente agregando openid, lo que indica que el usuario ha escaneado correctamente el código QR.

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()]);
	}

5. Compruebe si el código QR se escaneó correctamente.

Descripción lógica: utilice la función para consultar el estado de escaneo del código QR cada 2 segundos y consulte el openid en la tabla qrcode a través de scene_id en el backend. Si la columna openid correspondiente está vacía, significa que se trata de un nuevo código QR. No hay escaneo de usuario. Si la columna openid correspondiente no está vacía, significa que ha sido escaneado. Si el escaneo tiene éxito, se enviará el mensaje y la página será redirigida.

código de interfaz 

// 每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)
                    
                }
            }     
       })
}

código de fondo

    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','非法请求');
         }
     }

Supongo que te gusta

Origin blog.csdn.net/qq_25285531/article/details/130823460
Recomendado
Clasificación