- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章基于 Swoole 的微信扫码登录功能实现代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
随着微信的普及,扫码登录方式越来越被现在的应用所使用。它因为不用去记住密码,只要有微信号即可方便快捷登录。微信的开放平台原生就有支持扫码登录的功能,不过大部分人还是在用公众平台,所以扫码登录只能自行实现。这里基于微信公众平台的带参数临时二维码,并且结合 Swoole 的 WebSocket 服务实现扫码登录。大体流程如下:
客户端打开登录界面,连接到 WebSocket 服务 。
WebScoket 服务生成带参数二维码返回给客户端 。
用户扫描展示的带参数二维码 。
微信服务器回调扫码事件并通知开发者服务器 。
开发者服务器通知 WebSocket 服务 。
WebSocket 服务通知客户端登录成功 。
连接 WebSocket 服务 。
安装完 Swoole 之后,我们需用使用到 WebSocket 服务。新建一个 WebSocket 服务非常简单:
- $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) {
- });
这里的 message 回调其实用不到,因为都是服务端下发消息的,但是必须设定一个。设定的端口号如果低于 1024 则必须要有 root 权限,服务器记得去防火墙开启该端口.
生成带参数二维码 。
WebSocket 服务在客户端连接成功后,需要生成一张微信的带参数二维码返回给客户端展示:
- $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_为前缀,后面为二维码的参数值
这里要注意一点:微信已关注扫码推送的 EventKey 是没有 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);
- }
这里的 EventKey 实际上就是连接 WebSocket 的客户端文件描述符,获取到扫码用户的 OPEN_ID ,根据用户的 OPEN_ID 获取用户信息,通知 WebSocket 服务,响应文本消息给微信.
这里一个比较麻烦的点就是如何通知 WebSocket 服务,我们知道处理微信回调的代码是是不在 WebSocket 服务上的,那么不同 Server 间如何通信呢?Swoole 官方给出的解决方案有两个:
额外监听一个UDP端口 。
使用 swoole_client 作为客户端访问 Server 。
这里我们选择第二个方案,Swoole 1.8 版本支持一个 Server 监听多个端口,我们在 WebSocket 服务新增监听一个 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) {
- });
主服务器是 WebSocket 或 Http 协议,新监听的 TCP 端口默认会继承主 Server 的协议设置,必须单独调用 set 方法设置新的协议才会启用新协议 。
然后我们就可以在扫码回调的进程中去通知 WebSocket 服务:
- 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);
- }
通知登录成功 。
在 WebSocket 服务收到登录成功的通知后,就可以根据需要处理一下用户信息,然后把用户信息传递给客户端的浏览器展示结果,还记得我们刚刚新监听的 TCP 端口吗?就可以在 receive 事件中处理:
- $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);
- });
最后登录的界面:
总结 。
整个过程并不难,主要的两个难点就是对应连接用户的扫码用户、不同 Server 之间的通信,我们的解决办法就是把连接的文件描述符作为临时二维码场景值(这里也可以采用 Redis 来存储映射关系)、监听新的 TCP 端口来接受通知消息。可以访问http://wechat.sunnyshift.com/index.php试试看,记得要用电脑打开.
以上所述是小编给大家介绍的基于 Swoole 的微信扫码登录功能实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持.
最后此篇关于基于 Swoole 的微信扫码登录功能实现代码的文章就讲到这里了,如果你想了解更多关于基于 Swoole 的微信扫码登录功能实现代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试为我的用户提供使用 Google 或 Facebook 登录的选项。到目前为止,我找到了一个实现 Google 登录流程的示例,但如果我可以在同一 Activity 中实现类似的 Faceb
我有一个网页,它对用户是否登录很敏感。我使用的是 Google 登录 Javascript SDK。当用户到达此页面时,我想显示一个插页式广告(“正在加载...”),然后 1)如果用户已登录则呈现页面
我用 digitalocean 创建了一个 droplet,并使用 apt install mariadb-server 命令安装了 mariadb。现在我想使用 php 连接到我的服务器,我使用这个
这个问题在这里已经有了答案: Inno Setup - Signing fails with "Sign Tool failed with exit code 0x1" (2 个回答) 3年前关闭。
我正在尝试使用他们的新 API 实现 google 登录:https://developers.google.com/identity/sign-in/web/ 登录和注销工作正常。我的问题是我不知道
我的应用程序具有谷歌登录、Facebook 登录和 braintree 集成。 我已将以下代码放入 appdelegate.swift 中: func application(_ applicatio
我有一个 Flask 应用程序,最近在我的登录/退出表单中实现了 Flask-Login: @account.route('/sign-in', methods=['POST', 'GET']) de
friend 们,我是初学者级别的 ios swift 学习者。我一直在尝试在我的试用应用程序中进行谷歌登录。根据来自谷歌开发人员和其他教程的资源,我成功地使用 UIView 进行了登录。然后我试图在
我正在使用 Ionic 在 Codeigniter/Ion_Auth/codeigniter-restclient 之上构建登录系统,当我尝试从“ionic 服务器”登录时,登录可以正常工作,但对 L
在 Docker 文件中我有这个 FROM ubuntu RUN apt update && apt -y upgrade RUN apt install -y sudo # Setup ops us
对于 Java 开发,我使用 Slf4j 和 Logback。 Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.de
在 Scala 应用程序中进行日志记录的好方法是什么?与语言哲学一致的东西,不会使代码困惑,并且维护成本低且不引人注目。以下是基本要求列表: 简单 不会使代码困惑。 Scala 以其简洁而著称。我不希
我正在尝试将我的登录名转换为 Retrofit2 我的旧 LoginActivity: public class LoginActivity extends Activity { private st
我正在尝试让 google+ 登录在 android 上运行。我的问题是,每当我使用 eclipse 运行它时,google 开发站点上提供的示例都能完美运行。当我签署 apk 并在我的设备上手动安装
这个问题已经有答案了: JS Simple but Safe Login? [closed] (1 个回答) 已关闭 6 年前。 我正在尝试使用 JavaScript 创建登录页面。它实际上只是一个带
其他章节请看: react 高效高质量搭建后台系统 系列 登录 本篇将完成 登录模块 。效果和 spug 相同: 需求 如下:
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 1 年前。
我在使用 ReactJs 中的 facebook-login 组件时遇到问题,代码与文档中的完全一样,但仍然无法正常工作。你能帮我找出我做错了什么吗? import React, { Componen
我有一个项目,其中包含许多具有自己的日志记录的“工具”类。这些日志文件是在应用程序启动时创建的,但在使用之前一直为空。 是否可以告诉logback在启动时不应该创建空文件?但是仅在使用它们时? 不知何
我正在创建一个需要用户授权才能访问某些功能的网站。我目前正在研究用户如何创建帐户以及如何利用 session 来授权他们的登录。用户信息存储在名为 user 的 MySQL 表中,其中可能包括用户名和
我是一名优秀的程序员,十分优秀!