Maison > Article > développement back-end > Explication détaillée de l'implémentation par Edusoho de l'exemple de fonction de connexion par analyse de code
1. Introduction et exigences du projet
edusoho est une version commerciale de la plateforme d'éducation en ligne. Le projet lui-même est développé sur la base du framework symfony2. et il n'y a pas beaucoup d'exigences. Basé sur la modification du propre code d'edusoho, le client peut scanner le code QR pour se connecter au PC. La raison pour laquelle le code d'edusoho n'est pas trop modifié est d'éviter les erreurs lors de la prochaine mise à niveau de la version principale.
2. Informations sur la version et applications requises
edusoho 7.5.14
php 5.5.25
bibliothèque php GD
memcache (memcache est utilisé cette fois comme support de stockage et peut être remplacé par redis) Cliquez ici pour télécharger
phpqrcde (plug-in de génération de code QR php)
3. Idées d'implémentation
Cliquez sur le bouton de numérisation de page pour envoyer une requête à PHP. PHP génère un code QR et enregistre la chaîne de vérification du signe dans Memcache. est réussi, la page affiche la deuxième page. Le code QR attend que le code soit scanné et utilise ajax pour demander la méthode d'arrière-plan de manière à vérifier si le code a été scanné. Après avoir scanné le code avec votre téléphone mobile, accédez au lien URL dans le code QR. PHP enregistre l'identification du code numérisé et renvoie l'état du code numérisé à ajax. La première page indique que le code a été numérisé et envoie à nouveau un sondage ajax à. confirmer si la connexion a été confirmée. Une fois la numérisation du code terminée, l'application affichera la page de connexion, cliquera sur Confirmer et transmettra le nom d'utilisateur et la chaîne de vérification de signature à la méthode en arrière-plan. Une fois la vérification en arrière-plan réussie, le nom d'utilisateur, le signe et le code d'état seront renvoyés. à l'ajax frontal.
Puisque l'exigence n'est pas de changer le propre code d'edusoho, nous empruntons le propre identifiant d'edusoho lors de la connexion, c'est-à-dire, remplissons le nom d'utilisateur renvoyé par ajax dans la zone du nom d'utilisateur, remplissons la connexion dans la zone du mot de passe. , et déclenchez le bouton de soumission de connexion. Seules quelques lignes de code ont été ajoutées à la zone de vérification du mot de passe de connexion, et la vérification du mot de passe a été modifiée en vérification de signature. (La méthode de connexion utilisée par symfony2 est la connexion configurée pour la sécurité. Nous verrons plus tard où modifier la vérification du mot de passe. Si vous ne la connaissez pas, vous pouvez vous référer à la connexion de sécurité)
4. Code et étapes de mise en œuvre
1. Générer le code QR de connexion
(1) Configurez d'abord la route d'accès dans router.yml sous personnalisé (veuillez vous référer à la configuration pour les autres méthodes de routage par vous-même. La configuration du routage des méthodes suivantes ne sera pas décrite en détail)
(2) Cliquez sur le code js du bouton scan (la clé peut être stockée dans le cookie, cet exemple est écrit directement dans le champ caché de la page)
//点击扫码弹出框$('.scanqrcode').click(function (){ $('.login-section').hide();//隐藏登陆框$('.qrcode').show();//弹窗$('.timeout').hide(); $('.barcode-container.scanned .status.scanned, .barcode-container.scanned .mask').hide(); $('.login_op').show();//显示遮罩层//请求二维码 $.ajax({ type: "POST", dataType: "json", url: "/login/create/qrcode", success: function (data) {if(data.status==1){var qrcodeimg = '../../assets/img/qrcodeimg/'+data.msg+'.png';//把key放进隐藏域$('#key').val(data.msg);//替换二维码$('.qrcode-img').attr('src',qrcodeimg);//触发定时任务,查看是否已扫码var inter = setInterval("is_sacn_qrcode();",3000); $('#timing').val(inter); } } }); });
(3) Ecrivez la méthode createQrcode pour générer le code php de l'image QR code (le doString est un algorithme pour générer des chaînes de signes. Veuillez inventer et créer par vous-même. La meilleure chose est que les résultats générés seront différents à chaque fois)
//生成登录二维码public function CreateQrcodeAction(){ob_start();$url = 'http://'.$_SERVER['HTTP_HOST'];//获取当前的url$http = $url.'/login/mobile/scan/qrcode';//确认扫码的url方法$key = $this->getRandom(30);//存放在memcache中的键值,随机32位字符串$_SESSION['qrcode_name'] = $key;//把key当做图片的名字存在session里$sgin_data = $this->doString();//生成sign字符串的基本算法$sgin = strrev(substr($key,0,2)) . $sgin_data;//截取前两位并反转$value = $http.'?key='.$key.'&type=1';//二维码内容$errorCorrectionLevel = 'H';//容错级别$matrixPointSize = 8;//生成图片大小 //生成二维码图片\QRcode::png($value, 'qrcode.png', $errorCorrectionLevel, $matrixPointSize, 0);$logo = "assets/img/qrcodeimg_logo.png";//准备好的logo图片$QR = 'qrcode.png';//已经生成的原始二维码图if ($logo !== FALSE) {$QR = imagecreatefromstring(file_get_contents($QR));$logo = imagecreatefromstring(file_get_contents($logo));$QR_width = imagesx($QR);//二维码图片宽度$QR_height = imagesy($QR);//二维码图片高度$logo_width = imagesx($logo);//logo图片宽度$logo_height = imagesy($logo);//logo图片高度$logo_qr_width = $QR_width / 3;$scale = $logo_width/$logo_qr_width;$logo_qr_height = $logo_height/$scale;$from_width = ($QR_width - $logo_qr_width) / 2;//重新组合图片并调整大小imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,$logo_qr_height, $logo_width, $logo_height); }//输出图片$img = imagepng($QR, 'assets/img/qrcodeimg/'.$key.'.png');$return = array('status'=>0,'msg'=>'');if($img){$mem = new \Memcache();$mem->connect('127.0.0.1',11211);$res = json_encode(array('sign'=>$sgin,'type'=>0));//存进memcache,过期时间三分钟$mem->set($key,$res,0,180);//180$return = array('status'=>1,'msg'=>$key); }return $this->createJsonResponse($return); }
2. fait apparaître le code QR sur la page et lance l'interrogation ajax pour demander s'il faut scanner le code
(1) Rendu d'affichage :
(2) js code pour demander s'il faut scanner le code (interrogation continue si le code n'est pas scanné, si le code a été scanné, fermez la méthode "Vérifier si le code a été scanné", activez la connexion "Vérifier si le code est confirmé" " méthode d'interrogation, fermez la boîte de code QR pour effacer toutes les méthodes)
//查看是否已扫码function is_sacn_qrcode (){ $.ajax({ type: "POST", dataType: "json", url: " /login/scan/qrcode", success: function (data) {if(data.status==1){//扫码成功$('.barcode-container.scanned .status.scanned, .barcode-container.scanned .mask').show();//取消定时任务,清除cookieclearInterval($('#timing').val()); $('#timing').val('');////定时2秒关闭弹窗//setTimeout(function(){// $('.qrcode').hide();//},2000);//查看是否已确认登录var is_login = setInterval("is_login();",3000); $('#is_login').val(is_login);//$.cookie('is_login', is_login);}else if(data.status==2){ $('.timeout,.mask').show();//取消定时任务,清除cookieclearInterval($('#timing').val()); $('#timing').val(''); } } }); }
(3) Vérifiez si le code php a été scanné
= ['qrcode_name' = ->connect('127.0.0.1',11211 = json_decode(->get(),(( = ('status'=>2,'msg'=>'已过期'(['type' = ('status'=>1,'msg'=>'成功' = ('status'=>0,'msg'=>'' ->createJsonResponse(
(4) Code PHP scanné par le client
//移动设备扫码public function mobileScanQrcodeAction(Request $request,$key){$key = $_GET['key'];$url = 'http://'.$_SERVER['HTTP_HOST'];$agent=$_SERVER["HTTP_USER_AGENT"];if (!(strpos($agent, 'MicroMessenger') === false)) {// 获取版本号 //preg_match('/.*?(MicroMessenger\/([0-9.]+))\s*/', $agent, $matches);$app_url = 'http://club.risecenter.com/wap_app.html';// 微信浏览器,跳转至下载APP页面(可判断非指定app浏览器都跳转至此页面)return $this->redirect($app_url); }$http = $url.'/login/qrcodedoLogin';//返回确认登录的链接$mem = new \Memcache();$mem->connect('127.0.0.1',11211);$data = json_decode($mem->get($key),true);$data['type']=1;//增加type值,用来判断是否已扫码$res = json_encode($data);$mem->set($key,$res,0,180);$http = $http.'?key='.$key.'&type=scan';$return = array('status'=>1,'msg'=>$http);return $this->createJsonResponse($return); }
3 Déterminez s'il faut confirmer la connexion après avoir scanné avec succès le code
(1 ) Rendu d'une analyse de code réussie :
(2) Après avoir scanné avec succès le code, demandez s'il faut se connecter au code js (le client confirme la connexion et transmet le nom d'utilisateur à ajax, et js Remplissez le nom et connectez-vous au formulaire de nom d'utilisateur et de mot de passe, déclenchant le bouton de soumission de connexion caché sur la page)
//查看是否已确认登录function is_login(){var key = $('#key').val(); $.ajax({ type: "POST", dataType: "json", url: "/login/entry/login", data:{ key:key }, success: function (data) {if(data.status==1){var uid = data.uid;var sign = data.sign;//取消定时任务,清除cookieclearInterval($('#is_login').val()); $('#is_login').val('');//隐藏扫码成功$('.barcode-container.scanned .status.scanned, .barcode-container.scanned .mask').hide();//弹出已确认$('.confirmed,.mask').show();//定时1秒确认登陆setTimeout(function(){//确认登录$('#login_username').val(data.user); $('#login_password').val(data.sign); $('#login-form').submit(); },1000); }else if(data.status==2){//取消定时任务,清除cookieclearInterval($('#is_login').val()); $('#is_login').val(''); alert(data.msg); } } }); }
(3) Interrogez le code php pour vérifier si la connexion a été confirmée
/** * 客户端扫码后登录 * $sign 客户端扫码时传递标识,与memcache中的做对比 * $key 网页端二维码中传递的key * $uid 客户端登陆后扫码传递的用户id * @return void */public function qrcodeDoLoginAction(Request $request,$login,$key,$sign){$login = $_GET['login'];$key = $_GET['key'];$sign = $_GET['sign'];$mem = new \Memcache();$mem->connect('127.0.0.1',11211);$data = json_decode($mem->get($key),true);//取出memcache的值if($data['sign']!=$sign){//验证传递的sign$return = array('status'=>0,'msg'=>'验证错误');return $this->createJsonResponse($return); }else{if($login){//手机扫码网页登陆,把用户名存进memcache$data['login'] = $login;$res = json_encode($data);$mem->set($key,$res,0,180);$return = array('status'=>1,'msg'=>'登录成功');return $this->createJsonResponse($return); }else{$return = array('status'=>0,'msg'=>'请传递正确的用户信息');return $this->createJsonResponse($return); } } }
4. Confirmer la connexion
À ce stade, nous avons atteint la dernière étape consistant à scanner le code QR pour vous connecter, et c'est aussi l'étape la plus critique, je ne sais pas si vous, lecteurs, l'avez fait. J'ai remarqué le mécanisme de connexion de sécurité de symfony2. Comment ça se passe ? Ignorons le principe pour l'instant, cela n'entre pas dans le cadre de cette discussion. La méthode checkAuthentication de
/src/topxia/WebBundle/Handler/AuthenticationProvider.php peut être modifiée directement, ou elle peut être héritée de custom puis modifiée.
Le code php est le suivant :
5. Paramètre d'expiration du code QR
Pour des raisons de sécurité, définir l'expiration du code QR est très important En tant qu'étape, dans tous les codes PHP, les données stockées dans memcache ont une limite de temps. Le temps dans cet exemple est de 3 minutes après l'expiration, memcache supprimera les enregistrements de données d'origine. Lorsque la requête ajax ne peut pas être saisie, il doit être affiché sur la page que le code QR a expiré et le code QR doit être actualisé.
Le rendu est le suivant :
Conclusion :
1. La connexion au scan code PHP n'est qu'un processus de confirmation, à chaque fois que vous accéder à l'interface La vérification de sécurité est particulièrement importante lorsque vous utilisez cette méthode. Cette méthode n'implique pas l'algorithme de vérification. Veuillez d'abord effectuer des ajustements supplémentaires en fonction de vos propres projets.
2. La méthode de sondage ajax est-elle faible ? Il existe de meilleures méthodes de mise en œuvre, telles que websocket, goeasy, etc. Tout le monde a des opinions différentes, mais il semble que l'analyse du code QR d'Alipay et de JD.com soit en cours d'interrogation, veuillez me pardonner si c'est faux.
3. Cette connexion par code scan n'est qu'un concept, pas seulement pour la plateforme edusoho. Tout peut être transplanté et utilisé, mais simplement en toute sécurité.
4. Vous ne me demanderez pas les codes html et css de la boîte de code QR front-end Après tout, vous êtes tous des experts.
5. Je suis vraiment reconnaissant de voir cela. Je n'ai pas écrit une histoire en vain. De plus, les experts devraient être plus cléments lorsqu'ils attaquent. J'ai aussi une deuxième version, qui est peut-être meilleure. que celui-ci.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!