1. 프로젝트 소개 및 요구사항
edusoho는 온라인 교육 플랫폼의 상용 버전입니다. 프로젝트 자체는 Symfony2 프레임워크를 기반으로 개발되었으므로 고객이 수정하지 않고도 목표를 달성할 수 있습니다. edusoho 고유의 코드를 QR 코드를 스캔하여 PC로 로그인하세요. edusoho 코드를 너무 많이 수정하지 않는 이유는 다음 번에 메인 버전을 업그레이드할 때 오류가 발생하지 않도록 하기 위함입니다.
2. 버전 정보 및 필수 애플리케이션
edusoho 7.5.14
php 5.5.25
php GD library
memcache (이번에는 저장 매체로 memcache를 사용하고, 대신 redis를 사용해도 됩니다.) Click me to download
phpqrcde (php 생성 QR 코드 플러그인)
3. 구현 아이디어
페이지 스캔 버튼을 클릭하여 php에 요청을 보내면 php는 QR 코드를 생성하고 서명 확인 문자열을 저장합니다. memcache, 요청 성공 후 페이지에 스캔 대기 중인 QR 코드가 표시되고, ajax를 사용하여 코드 스캔 여부를 확인하기 위해 폴링 방식으로 백그라운드 메소드를 요청합니다. 휴대폰으로 코드를 스캔한 후 QR 코드의 URL 링크에 액세스합니다. PHP는 스캔한 코드 식별을 저장하고 스캔된 코드 상태를 ajax로 반환합니다. 첫 페이지에는 코드가 스캔되었다는 메시지가 표시되고 ajax 폴링이 다시 전송됩니다. 로그인이 확인되었는지 확인하세요. 코드 스캔이 완료되면 앱에 로그인 페이지가 표시되고 확인을 클릭한 다음 사용자 이름과 서명 확인 문자열을 백그라운드 메서드에 전달합니다. 백그라운드 확인이 통과되면 사용자 이름, 서명 및 상태 코드가 반환됩니다. 프론트엔드 아약스로.
요구사항은 edusoho 자신의 코드를 변경하는 것이 아니기 때문에 로그인 시 edusoho 자신의 로그인 정보를 차용합니다. 즉, ajax에서 반환한 사용자 이름을 사용자 이름 상자에 입력하고, 비밀번호 상자에 로그인을 입력한 후, 로그인 제출 버튼에 비밀번호 확인 부분에 코드 몇 줄이 추가되었고, 비밀번호 확인이 서명 확인으로 변경되었습니다. (symfony2에서 사용하는 로그인 방법은 보안이 설정된 로그인입니다. 비밀번호 확인을 어디서 변경해야 하는지는 나중에 다루겠습니다. 익숙하지 않은 경우 보안 로그인을 참고하세요.)
4. 구현 코드 및 단계
1. 로그인 QR 코드 생성
(1) 먼저 사용자 정의에서 Routing.yml에 액세스 경로를 구성합니다. (다른 라우팅 방법은 직접 구성을 참조하십시오. 다음 방법의 라우팅 구성은 자세히 설명하지 않습니다.)
(2) 스캔 코드 버튼의 js 코드를 클릭합니다. (키를 쿠키에 저장할 수 있습니다. 이 예에서는 페이지의 숨겨진 필드에 직접 씁니다.)
//点击扫码弹出框$('.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) QR 코드 이미지에 대한 PHP 코드를 생성하는 createQrcode 메소드(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는 원본 데이터 레코드를 삭제합니다. Ajax가 데이터를 요청할 수 없으면 QR 코드가 만료되었다는 메시지가 페이지에 표시됩니다.
렌더링은 다음과 같습니다.
결론:
1. PHP 스캔 코드 로그인은 인터페이스에 액세스할 때마다 특히 중요합니다. 자신의 프로젝트에 따라 추가 조정을 하고, 아이디어를 먼저 생각해 보세요.
2. 아약스 폴링 방식이 낮은가요? websocket, goeasy 등 더 나은 구현 방법이 있습니다. 사람마다 의견이 다르지만 Alipay와 JD.com의 QR 코드 스캐닝이 폴링되는 것 같습니다. 틀렸다면 양해해 주시기 바랍니다.
3. 이 스캔 코드 로그인은 단지 개념일 뿐이며, edusoho 플랫폼뿐만 아니라 모든 것이 이식되어 사용될 수 있지만 안전합니다.
4. 프론트 엔드 QR 코드 상자의 html 및 css 코드를 묻지 않을 것입니다.
5. 제가 이런 이야기를 헛되이 쓰지 않았다는 사실이 정말 감사합니다. 또한 공격할 때 전문가들이 더 자비를 베풀어야 하는데, 이 버전이 더 나을 수도 있습니다. .
위 내용은 edusoho의 코드 스캐닝 로그인 기능 구현 예에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!