随着微信的普及,扫码登陆方法越来越被现今的应用所使用。它由于不用去记住密码,只要有微信号即可便捷快捷登入。微信的开放平台原生就有支持扫码登陆的功能,不过大部份人还是在用公众平台,所以扫码登陆只能自行实现。这儿基于微信公众平台的带参数临时二维码,但是结合的服务实现扫码登陆。大体流程如下:
顾客端打开登陆界面,联接到服务服务生成带参数二维码返回给顾客端用户扫描展示的带参数二维码微信服务器反弹扫码风波并通知开发者服务器开发者服务器通知服务服务通知顾客端登陆成功联接服务
安装完以后,我们需用使用到服务。新建一个服务十分简单:
$server = new swoole_websocket_server("0.0.0.0", 1099);
$server->on('open', function (swoole_websocket_server $server, $request) use ($config){
echo "server: handshake success with fd{$request->fd}n";
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
});
这儿的反弹虽然用不到,由于都是服务端下发消息的,并且必须设定一个。设定的端标语倘若高于1024则必需要有root权限,服务器记得去防火墙开启该端口。
生成带参数二维码
服务在顾客端联接成功后,须要生成一张微信的带参数二维码返回给顾客端展示:
$server->on('open', function (swoole_websocket_server $server, $request) use ($config){
$app = Factory::officialAccount($config['wechat']);
$result = $app->qrcode->temporary($request->fd, 120);
$url = $app->qrcode->url($result['ticket']);
$server->push($request->fd, json_encode([
'message_type' => 'qrcode_url',
'url' => $url
]));
});
我们在open反弹中,生成一张临时的二维码,二维码的场景值就是顾客端联接的文件描述符,这样就可以保证每位顾客端的惟一性。有效时间设置为120秒,避免一张二维码被多次扫码使用。消息push到顾客端的时侯必需要json,便捷顾客端处理。顾客端代码也很简单:
const socket = new WebSocket('ws://127.0.0.1:1099');
socket.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
if (data.message_type == 'qrcode_url'){
$('#qrcode').attr('src', data.url);
}
});
反弹扫码风波
在顾客端展示二维码后,须要提示用户扫码。对于用户扫临时的二维码,微信会触发相应的反弹风波,我们须要在该反弹风波中处理用户的扫码行为。其中我们须要用到微信传递过来的一些参数:
FromUserName 发送方帐号(一个OpenID)
MsgType 消息类型,event
Event 事件类型,subscribe
EventKey 事件 KEY 值,qrscene_为前缀,后面为二维码的参数值
这儿要注意一点:微信已关注扫码推送的是没有前缀的,只有未关注扫码之后关注才有。
收到微信反弹后我们首先要依照不同的风波类型做不同处理:
if ($message['MsgType'] == 'event'){
if ($message['Event'] == 'subscribe'){ //关注
return $this->subscribe($message);
}
if ($message['Event'] == 'unsubscribe') { //取消关注
return $this->unsubscribe($message);
}
if ($message['Event'] == 'SCAN'){ //已关注扫码
return $this->scan($message);
}
}else{
return "您好!欢迎使用 SwooleWechat 扫描登录";
}
这儿只讲解一个关注风波的业务逻辑,其他依据须要自行编码:
public function subscribe($message){
$eventKey = intval(str_replace('qrscene_', '', $message['EventKey']));
$openId = $message['FromUserName'];
$user = $this->app->user->get($openId);
$this->notify(json_encode([
'type' => 'scan',
'fd' => $eventKey,
'nickname' => $user['nickname']
]));
$count = $this->count($openId);
$msgTemp = "%s,登录成功!n这是你第%s次登录,玩的开心!";
return sprintf($msgTemp, $user['nickname'], $count);
}
这儿的实际上就是联接的顾客端文件描述符,获取到扫码用户的,按照用户的获取用户信息,通知服务,响应文本消息给微信。
这儿一个比较麻烦的点就是怎样通知服务,我们晓得处理微信反弹的代码是是不在服务上的,这么不同间怎么通讯呢?官方给出的解决方案有两个:
额外窃听一个UDP端口使用作为顾客端访问
这儿我们选择第二个方案,1.8版本支持一个窃听多个端口,我们在服务新增窃听一个TCP的端口:
$tcp_server = $server->addListener('0.0.0.0', 9999, SWOOLE_SOCK_TCP);
$tcp_server->set([]);
$tcp_server->on('receive', function ($serv, $fd, $threadId, $data) {
});
主服务器是或Http合同,新窃听的TCP端口默认会承继主的合同设置,必须单独调用set方式设置新的合同才能启用新合同
之后我们就可以在扫码反弹的进程中去通知服务:
public function notify($message){
$client = new swoole_client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', $this->config['notify_port'], -1)) {
return "connect failed. Error: {$client->errCode}n";
}
$ret = $client->send($message);
}
通知登陆成功
在服务收到登陆成功的通知后,就可以按照须要处理一下用户信息,之后把用户信息传递给顾客端的浏览器展示结果,还记得我们刚才新窃听的TCP端口吗?就可以在风波中处理:
$tcp_server->on('receive', function ($serv, $fd, $threadId, $data) {
$data = json_decode($data, true);
if ($data['type'] == 'scan'){
$serv->push($data['fd'], json_encode([
'message_type' => 'scan_success',
'user' => $data['nickname']
]));
}
$serv->close($fd);
});
最后登陆的界面:
发图太麻烦,自行去测试地址看。
点关注,不走失
好了诸位,以上就是这篇文章的全部内容了,能看见这儿的人呀,都是人才。之前说过,PHP方面的技术点好多微信扫码点单,也是由于太多了,实在是写不过来微信扫码点单,写过来了你们也不会看的太多,所以我这儿把它整理成了PDF和文档,假如有须要的可以
点击步入暗号:PHP+「平台」
更多学习内容可以访问
阿布阿布:【对标大厂】精品PHP构架师教程目录大全,只要你能看完保证工资上升一个台阶(持续更新)
以上内容希望帮助到你们,好多PHPer在进阶的时侯总会碰到一些问题和困局,业务代码写多了没有方向感,不晓得该从哪里入手去提高,对此我整理了一些资料,包括但不限于:分布式构架、高可扩充、高性能、高并发、服务器性能调优、TP6,,YII2,Redis,、Swoft、Kafka、Mysql优化、shell脚本、、微服务、Nginx等多个知识点中级进阶干货须要的可以免费分享给你们,须要的可以加入我的PHP技术交流群
免责声明:部分文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性,如本站文章和转稿涉及版权等问题,请作者在及时联系本站,我们会尽快为您处理。