1.准备好公众号的appid和appsecret,以及IP白名单
2.php代码写入
public function login_wx()
{
$data = Db::name('config')->where('config_key','WECHAT_CONFIG')->find();
$value = json_decode($data['value'],true);
$appid = $value['appid'];
$appsecret = $value['appsecret'];
$sceneId = uniqid();
$token = bin2hex(random_bytes(16));
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$access_token = $this->getAccessToken($appid, $appsecret);
$ticket = $this->getQRTicket($access_token,'604800',$sceneId);
$qrCodeURL = $this->getQRCode($ticket);
$data = [
'sceneid'=>$sceneId,
'token'=>$token,
'ctime'=>time(),
'dtime'=>time() + 300,
];
$res = Db::name('wxlogin')->insert($data);
$returns = [
'token'=>$token,
'url'=>$qrCodeURL,
];
if($res){
return json_encode($returns);
}
}
//验证用户
public function checkLogin() {
var_dump($_REQUEST);die;
$token = $_REQUEST['token'];
$data = Db::name('wxlogin')->where('token',$token)->find();
if($data['status'] == 1){ //已经登录
$returns = [
'code'=>1,
'msg'=>'已登录',
];
}
if($data['status'] == 3){ //二维码已过期
$returns = [
'code'=>3,
'msg'=>'二维码已过期',
];
}
if($data['status'] == 2){ //未登录
$returns = [
'code'=>2,
'msg'=>'未登录',
];
}
return json_encode($returns);
}
public function getQRCode($ticket) {
$url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . urlencode($ticket);
return $url; // 这个URL即为二维码图片的URL
}
public function getAccessToken($appid, $appsecret) {
$access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
$access_token_data = json_decode(file_get_contents($access_token_url), true);
return $access_token_data['access_token'];
}
// 生成二维码Ticket
public function getQRTicket($accessToken, $expireSeconds = 604800, $sceneId = 1) {
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$accessToken}";
$data = json_encode([
'expire_seconds' => $expireSeconds,
'action_name' => 'QR_SCENE',
'action_info' => ['scene' => ['scene_id' => $sceneId]]
]);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json",
'content' => $data,
'timeout' => 60
]
];
$context = stream_context_create($options);
$response = json_decode(file_get_contents($url, false, $context), true);
return $response['ticket'];
}
3.在公众号的 服务器配置的服务器地址(URL)里面写
$data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
if ( $data->Event == 'subscribe' || $data->Event == 'SCAN' ) { // 关注公众号 或者 已关注用户扫码
if (!empty($data->EventKey)) {
// 这里的qrscene_为前缀,后面跟的是你设置的参数值
$scene_id = str_replace('qrscene_', '', $data->EventKey);
//检测场景值是否过期
//没过期就 查询数据库wxlogin对饮的token返回给前端顺利登陆
$cinfo = Db::name('wxlogin')->where('sceneid',$scene_id)->find();
if(time() < $cinfo['dtime']){ //执行登录
$res = Db::name('wxlogin')->where('sceneid',$scene_id)->update(['status'=>'1']);
if($res){
// 向用户发送消息123
$this->sendTextMessage($data->FromUserName, $data->ToUserName, '恭喜您已经成功登录');
}
}else{ //已经过期。执行过期状态
$res = Db::name('wxlogin')->where('sceneid',$scene_id)->update(['status'=>'3']);
}
}
}
if ( $data->Event == 'unsubscribe' ) { // 用户取消关注公众号
}
4.微信给 服务器地址返回的信息 :这里做详细解释
这是接收到的数据
{"ToUserName":"gh_32219ed1e2ea","FromUserName":"o0czO6dbV0cfDFy96tHPr99m3Lxg","CreateTime":"1717421428","MsgType":"event","Event":"SCAN","EventKey":"1","Ticket":"gQEN8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyNVh6RVlXaGNmZUYxdVNZQ05DMW8AAgQ2wl1mAwSAOgkA"}
$data->MsgType
这是一个描述消息类型的字段。MsgType用来指示消息的种类,比如:
text 表示文本消息。
image 表示图片消息。
event 表示事件推送。
当MsgType的值为event时,表示接收到的是一个事件推送。事件推送不是用户直接发送的消息,而是某些用户行为或微信行为触发的通知,比如用户关注或取消关注公众号、用户扫描二维码等。
$data->Event:
当MsgType为event时,Event字段用来进一步指定事件的类型。例如:
subscribe 表示用户关注公众号事件。
unsubscribe 表示用户取消关注公众号。
SCAN 表示用户已关注公众号后扫描二维码。
CLICK 表示用户点击了自定义菜单。
在你的例子中,$data->Event == 'subscribe' 指的是用户关注公众号的事件。当用户首次关注公众号,或者之前取消关注后再次关注时,你的服务器会接收到这个事件
$data->EventKey
EventKey是与特定事件相关联的一个参数,主要用在事件推送(event)中。这个参数的值取决于具体的事件类型:
关于二维码扫描:
当用户扫描带参数的二维码时,无论是已关注还是未关注用户,微信都会将事件推送到你的服务器。这时,EventKey将包含与该二维码相关的信息:
对于未关注用户扫描后关注的事件(subscribe),EventKey会以qrscene_为前缀,后接你创建二维码时定义的场景值(scene_id或scene_str)。例如,如果场景值是123,EventKey就会是qrscene_123。
对于已关注用户扫描二维码的事件(SCAN),EventKey直接是二维码的场景值,比如123。
自定义菜单事件:
如果用户点击了自定义菜单项,且该菜单项是点击类型(click),则EventKey是与该菜单项相关联的key值,这个值是在设置自定义菜单时由开发者指定的。
$data->Ticket
Ticket参数通常与二维码扫描事件相关联。当用户扫描一个带参数的二维码时,微信会在推送的事件信息中包含一个Ticket值。这个Ticket可以视为该次扫描事件的一个唯一标识符。具体来说:
二维码扫描事件:
当用户扫描带参数二维码时,无论是关注还是未关注,事件推送中都会包含Ticket参数。这个Ticket是在生成二维码时由微信生成并提供的,可以用来获取扫描者和二维码的详细信息。
标签:微信,对接,二维码,用户,token,EventKey,PHP,data,事件
From: https://www.cnblogs.com/79524795-Tian/p/18229889