PHP扫码登录的实现原理是怎样的?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1671个文字,预计阅读时间需要7分钟。
扫一扫登录账号,相较于传统的账号密码登录,更加便捷、快速、灵活,在实际使用中更受用户欢迎。本文主要介绍了扫一扫登录的原理及整体流程,包括二维码的生成/获取、过期失效的处理、登录状态等。
由于扫码登录比账号密码登录更方便、快捷、灵活,在实际使用中更受到用户的欢迎。本文主要介绍了扫码登录的原理及整体流程,包含了二维码的生成/获取、过期失效的处理、登录状态的监听。
扫码登录的原理
整体流程
为方便理解,我简单画了一个 UML 时序图,用以描述扫码登录的大致流程!
总结下核心流程:
请求业务服务器获取用以登录的二维码和 UUID。
通过 websocket 连接 socket 服务器,并定时(时间间隔依据服务器配置时间调整)发送心跳保持连接。
用户通过 APP 扫描二维码,发送请求到业务服务器处理登录。根据 UUID 设置登录结果。
socket 服务器通过监听获取登录结果,建立 session 数据,根据 UUID 推送登录数据到用户浏览器。
用户登录成功,服务器主动将该 socker 连接从连接池中剔除,该二维码失效。
关于客户端标识
也就是 UUID,这是贯穿整个流程的纽带,一个闭环登录过程,每一步业务处理都是围绕该次的 UUD 进行处理的。UUID 的生成有根据 session_id 的也有根据客户端 ip 地址的。个人还是建议每个二维码都有单独的 UUID,适用场景更广一些!
关于前端和服务器通讯
前端肯定是要和服务器保持一直通讯的,用以获取登录结果和二维码状态。看了下网上的一些实现方案,基本各个方案都有用的:轮询、长轮询、长链接、websocket。也不能肯定的说哪个方案好哪个方案不好,只能说哪个方案更适用于当前应用场景。个人比较建议使用长轮询、websocket 这种比较节省服务器性能的方案。
关于安全性
扫码登录的好处显而易见,一是人性化,再就是防止密码泄漏。但是新方式的接入,往往也伴随着新的风险。所以,很有必要再整体过程中加入适当的安全机制。例如:
- 强制 HTTPS 协议
- 短期令牌
- 数据签名
- 数据加密
扫码登录的过程演示
代码实现和源码后面会给出。
开启 Socket 服务器
访问登录页面
可以看到用户请求的二维码资源,并获取到了 qid 。
获取二维码时候会建立相应缓存,并设置过期时间:
之后会连接 socket 服务器,定时发送心跳。
此时 socket 服务器会有相应连接日志输出:
用户使用 APP 扫码并授权
服务器验证并处理登录,创建 session,建立对应的缓存:
Socket 服务器读取到缓存,开始推送信息,并关闭剔除连接:
前端获取信息,处理登录:
扫码登录的实现
注意:本 Demo 只是个人学习测试,所以并未做太多安全机制!
Socket 代理服务器
使用 Nginx 作为代理 socke 服务器。可使用域名,方便做负载均衡。本次测试域名:loc.websocket.net
websocker.conf
server { listen 80; server_name loc.websocket.net; root /www/websocket; index index.php index.html index.htm; #charset koi8-r; access_log /dev/null; #access_log /var/log/nginx/nginx.localhost.access.log main; error_log /var/log/nginx/nginx.websocket.error.log warn; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location / { proxy_pass php-cli:8095/; proxy_localhost/qrcode/code.php', type:'post', dataType: "json", async: false, success:function (result) { $('#qrcode').attr('src', result.img); $('#qid').val(result.qid); } }); if ("WebSocket" in window) { if (typeof ws != 'undefined'){ ws.close(); null != wsTid && window.clearInterval(wsTid); } ws = new WebSocket("ws://loc.websocket.net?qid=" + $('#qid').val()); ws.onopen = function() { console.log('websocket 已连接上!'); }; ws.onmessage = function(e) { // todo: 本函数做登录处理,登录判断,创建缓存信息! console.log(e.data); var result = JSON.parse(e.data); console.log(result); alert('登录成功:' + result.name); }; ws.onclose = function() { console.log('websocket 连接已关闭!'); $('#qrcode-exp').show(); null != wsTid && window.clearInterval(wsTid); }; // 发送心跳 wsTid = window.setInterval( function () { if (typeof ws != 'undefined') ws.send('1'); }, 50000 ); } else { // todo: 不支持 WebSocket 的,可以使用 js 轮询处理,这里不作该功能实现! alert('您的浏览器不支持 WebSocket!'); } }</script> </body> </html>
登录处理
测试使用,模拟登录处理,未做安全认证!!
<?php require_once dirname(__FILE__) . '/lib/RedisUtile.php'; require_once dirname(__FILE__) . '/lib/Common.php';/** * ------- 登录逻辑模拟 -------- * 请根据实际编写登录逻辑并处理安全验证 */$qid = $_GET['qid']; $uid = $_GET['uid']; $data = array();switch ($uid) { case '1': $data['uid'] = 1; $data['name'] = '张三'; break; case '2': $data['uid'] = 2; $data['name'] = '李四'; break; } $data = json_encode($data); $redis = \lib\RedisUtile::getInstance(); $redis->setex(\lib\Common::getQidLoginKey($qid), 1800, $data);
更多相关知识,请访问PHP中文网!
以上就是分享PHP扫码登录原理及实现方法的详细内容,更多请关注自由互联其它相关文章!
本文共计1671个文字,预计阅读时间需要7分钟。
扫一扫登录账号,相较于传统的账号密码登录,更加便捷、快速、灵活,在实际使用中更受用户欢迎。本文主要介绍了扫一扫登录的原理及整体流程,包括二维码的生成/获取、过期失效的处理、登录状态等。
由于扫码登录比账号密码登录更方便、快捷、灵活,在实际使用中更受到用户的欢迎。本文主要介绍了扫码登录的原理及整体流程,包含了二维码的生成/获取、过期失效的处理、登录状态的监听。
扫码登录的原理
整体流程
为方便理解,我简单画了一个 UML 时序图,用以描述扫码登录的大致流程!
总结下核心流程:
请求业务服务器获取用以登录的二维码和 UUID。
通过 websocket 连接 socket 服务器,并定时(时间间隔依据服务器配置时间调整)发送心跳保持连接。
用户通过 APP 扫描二维码,发送请求到业务服务器处理登录。根据 UUID 设置登录结果。
socket 服务器通过监听获取登录结果,建立 session 数据,根据 UUID 推送登录数据到用户浏览器。
用户登录成功,服务器主动将该 socker 连接从连接池中剔除,该二维码失效。
关于客户端标识
也就是 UUID,这是贯穿整个流程的纽带,一个闭环登录过程,每一步业务处理都是围绕该次的 UUD 进行处理的。UUID 的生成有根据 session_id 的也有根据客户端 ip 地址的。个人还是建议每个二维码都有单独的 UUID,适用场景更广一些!
关于前端和服务器通讯
前端肯定是要和服务器保持一直通讯的,用以获取登录结果和二维码状态。看了下网上的一些实现方案,基本各个方案都有用的:轮询、长轮询、长链接、websocket。也不能肯定的说哪个方案好哪个方案不好,只能说哪个方案更适用于当前应用场景。个人比较建议使用长轮询、websocket 这种比较节省服务器性能的方案。
关于安全性
扫码登录的好处显而易见,一是人性化,再就是防止密码泄漏。但是新方式的接入,往往也伴随着新的风险。所以,很有必要再整体过程中加入适当的安全机制。例如:
- 强制 HTTPS 协议
- 短期令牌
- 数据签名
- 数据加密
扫码登录的过程演示
代码实现和源码后面会给出。
开启 Socket 服务器
访问登录页面
可以看到用户请求的二维码资源,并获取到了 qid 。
获取二维码时候会建立相应缓存,并设置过期时间:
之后会连接 socket 服务器,定时发送心跳。
此时 socket 服务器会有相应连接日志输出:
用户使用 APP 扫码并授权
服务器验证并处理登录,创建 session,建立对应的缓存:
Socket 服务器读取到缓存,开始推送信息,并关闭剔除连接:
前端获取信息,处理登录:
扫码登录的实现
注意:本 Demo 只是个人学习测试,所以并未做太多安全机制!
Socket 代理服务器
使用 Nginx 作为代理 socke 服务器。可使用域名,方便做负载均衡。本次测试域名:loc.websocket.net
websocker.conf
server { listen 80; server_name loc.websocket.net; root /www/websocket; index index.php index.html index.htm; #charset koi8-r; access_log /dev/null; #access_log /var/log/nginx/nginx.localhost.access.log main; error_log /var/log/nginx/nginx.websocket.error.log warn; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location / { proxy_pass php-cli:8095/; proxy_localhost/qrcode/code.php', type:'post', dataType: "json", async: false, success:function (result) { $('#qrcode').attr('src', result.img); $('#qid').val(result.qid); } }); if ("WebSocket" in window) { if (typeof ws != 'undefined'){ ws.close(); null != wsTid && window.clearInterval(wsTid); } ws = new WebSocket("ws://loc.websocket.net?qid=" + $('#qid').val()); ws.onopen = function() { console.log('websocket 已连接上!'); }; ws.onmessage = function(e) { // todo: 本函数做登录处理,登录判断,创建缓存信息! console.log(e.data); var result = JSON.parse(e.data); console.log(result); alert('登录成功:' + result.name); }; ws.onclose = function() { console.log('websocket 连接已关闭!'); $('#qrcode-exp').show(); null != wsTid && window.clearInterval(wsTid); }; // 发送心跳 wsTid = window.setInterval( function () { if (typeof ws != 'undefined') ws.send('1'); }, 50000 ); } else { // todo: 不支持 WebSocket 的,可以使用 js 轮询处理,这里不作该功能实现! alert('您的浏览器不支持 WebSocket!'); } }</script> </body> </html>
登录处理
测试使用,模拟登录处理,未做安全认证!!
<?php require_once dirname(__FILE__) . '/lib/RedisUtile.php'; require_once dirname(__FILE__) . '/lib/Common.php';/** * ------- 登录逻辑模拟 -------- * 请根据实际编写登录逻辑并处理安全验证 */$qid = $_GET['qid']; $uid = $_GET['uid']; $data = array();switch ($uid) { case '1': $data['uid'] = 1; $data['name'] = '张三'; break; case '2': $data['uid'] = 2; $data['name'] = '李四'; break; } $data = json_encode($data); $redis = \lib\RedisUtile::getInstance(); $redis->setex(\lib\Common::getQidLoginKey($qid), 1800, $data);
更多相关知识,请访问PHP中文网!
以上就是分享PHP扫码登录原理及实现方法的详细内容,更多请关注自由互联其它相关文章!

