ホームページ >バックエンド開発 >PHPチュートリアル >edusohoのコードスキャンログイン機能実装例の詳細説明

edusohoのコードスキャンログイン機能実装例の詳細説明

零下一度
零下一度オリジナル
2017-06-30 15:51:023323ブラウズ

1. プロジェクトの紹介と要件

edusoho はオンライン教育プラットフォームの商用バージョンであり、プロジェクト自体は symfony2 フレームワークに基づいて開発されており、顧客は変更することなく目標を達成できることが必要です。 edusoho 独自のコードをスキャンして PC からログインします。 edusoho のコードをあまり修正しないのは、次回の本体バージョンをアップグレードする際のエラーを避けるためです。

2. バージョン情報と必要なアプリケーション

edusoho 7.5.14

php 5.5.25

php GD library

memcache (今回は記憶媒体としてmemcacheを使用していますが、代わりにredisを使用することもできます) Click meダウンロードするには

phpqrcde (php 生成 QR コード プラグイン)

3. 実装アイデア

ページ スキャン ボタンをクリックして php にリクエストを送信すると、php は QR コードを生成し、署名検証文字列を保存しますmemcache, request 成功すると、ページにはスキャンを待機している QR コードが表示され、Ajax を使用してポーリング方式でバックグラウンド メソッドをリクエストし、コードがスキャンされたかどうかを確認します。携帯電話でコードをスキャンした後、QR コードの URL リンクにアクセスすると、PHP はスキャンされたコード ID を保存し、スキャンされたコードのステータスを ajax に返します。コードがスキャンされたことを示すプロンプトが表示され、ajax ポーリングが再度送信されます。ログインが確認されたかどうかを確認します。コードのスキャンが完了すると、APP はログイン ページを表示し、ユーザー名と署名検証文字列をバックグラウンド メソッドに渡します。バックグラウンド検証が完了すると、ユーザー名、署名、ステータス コードが返されます。フロントエンドの ajax に。

要件は edusoho 独自のコードを変更しないことであるため、ログイン時に edusoho 独自のログインを借用します。つまり、ajax から返されたユーザー名をユーザー名ボックスに入力し、パスワード ボックスにサインを入力し、ログイン送信ボタン パスワード検証セクションに数行のコードが追加され、パスワード検証が署名検証に変更されました。 (symfony2 で使用されるログイン方法は、セキュリティが設定されたログインです。パスワード検証を変更する場所については後ほど説明します。慣れていない場合は、セキュリティ ログインを参照してください)

4. 実装コードと手順

1. ログイン用QRコードの生成

(1) まず、custom 配下の routing.yml にアクセスルートを設定します (他のルーティング方法の設定は各自で参照してください。以下のメソッドのルーティング設定については詳しく説明しません)

(2) スキャンコードボタンの js コードをクリックします (キーを Cookie に保存できます。この例では、ページの隠しフィールドに直接書き込みます)

   //点击扫码弹出框$('.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) createQrcode メソッドで QR コード画像の PHP コードを生成します (doString メソッドは記号文字列を生成するアルゴリズムであり、自分で考案して作成してください。毎回異なる結果を生成するのが最善です)

    //生成登录二维码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 jquery はページの QR コードをポップアップし、コードをスキャンするかどうかをクエリするための Ajax ポーリングを開始します

(1) 表示レンダリング:

(2) コードをスキャンするかどうかをリクエストする JS コード (コードをスキャンせずに継続的にポーリングします)コードをスキャンした後、「コードがスキャンされたかどうかを確認する」メソッドをオフにし、「ログインが確認されたかどうかを確認する」メソッドのポーリングをオンにし、2D すべてのメソッドをオフにしてコード ボックスをクリアします)

//查看是否已扫码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) PHP コードがスキャンされたかどうかを確認します

  = ['qrcode_name' = ->connect('127.0.0.1',11211 = json_decode(->get(),(( = ('status'=>2,'msg'=>'已过期'(['type' = ('status'=>1,'msg'=>'成功' = ('status'=>0,'msg'=>'' ->createJsonResponse(

(4) クライアントによってスキャンされた PHP コード

    //移动设备扫码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. スキャンが成功したかどうかを確認します ログインを確認します

(1) 成功しましたスキャン レンダリング:

(2) QR コードのスキャンに成功したら、js コードにログインするかどうかをクエリします (クライアントはログインを確認してユーザー名を ajax に渡し、js がユーザー名を入力して署名します)。パスワードフォーム、ページ上に隠されたログイン送信ボタンをトリガーします)

//查看是否已确认登录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) ログインが確認されたかどうかをクエリする PHP コード

    /**
     * 客户端扫码后登录
     * $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. ログインを確認する

この時点で、QR コードをスキャンしてログインするという最後のステップに達しました。これは、読者の皆さんが symfony2 のセキュリティ ログイン メカニズムについてどう思っているかと思います。原則第一 結局のところ、それはこの議論の範囲内ではありません。何を変える必要があるかについてだけ話しましょう。

/src/topxia/WebBundle/Handler/AuthenticationProvider.php の checkAuthentication メソッドは、直接変更することも、カスタムから継承して変更することもできます。

php コードは次のとおりです:

5. QR コードの有効期限の設定

セキュリティ上の理由から、QR コードの有効期限の設定はすべての PHP コードで重要なステップであり、memcache に保存されるデータには期限があります。この例の時間は 3 分です。有効期限が切れると、memcache は元のデータ レコードを削除し、QR コードの有効期限が切れたことをページに表示します。

レンダリングは次のとおりです:

結論:

1. PHP スキャン コード ログインは、インターフェイスにアクセスするたびに特に重要です。この方法には検証アルゴリズムは含まれません。ご自身のプロジェクトに合わせてさらに調整し、アイデアを出してみてください。

2. ajax ポーリング方式は低いですか? websocket や goeasy など、もっと良い実装方法があります。人それぞれ意見は違いますが、Alipay と JD.com の QR コード スキャンはポーリングのようです。間違っていたらご容赦ください。

3. このスキャンコードログインは単なる概念であり、edusoho プラットフォームに限らず、あらゆるものを移植して使用できますが、安全にご注意ください。

4. フロントエンドの QR コード ボックスの HTML と CSS コードを私に尋ねることはありません。結局のところ、皆さんは専門家です。

5. これを見ることができて本当に感謝しています。私が無駄にストーリーを書いたわけではありません。また、このバージョンよりも優れたバージョンもあるはずです。 。

以上がedusohoのコードスキャンログイン機能実装例の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。