掃碼登陸 之我見

前幾天買阿里云服務器的時候,被掃碼登陸給吸引到了。然后就一直在琢磨自己的實現方式。也許是巧合吧,昨晚竟然在夢中找到了一個自認為還不錯的實現思路。但是已經凌晨了,為了防止忘記,趕緊寫了個小紙條放在床邊。于是今天上午就著手編碼做了個雛形。

作此文,以記之。

原理

感覺還是應該先進行聲明一下。

純屬個人拙見,如果有些許不當,還望海涵。

按照我掃碼登陸的親身經歷,可以分為下面幾個階段。

打開網頁

拿阿里云來說,打開首頁點擊登錄按鈕之后,就會跳轉到下面的這個網頁,讓我們使用阿里云手機客戶端 掃碼。

阿里云登陸

掃碼階段

其實我們可能會很疑惑,為什么一掃碼, 人家就能知道咱掃過了呢?而且就這么真的登陸成功了?

其實如果讓我自己來做的話,關鍵就在于這個阿里云手機客戶端。眾所周知,二維碼只是個用于傳遞數據的工具,它本身并不能幫助我們確認是否被掃碼,被誰掃了。

但是關鍵就在于這個數據。其實這個數據至關重要,因為借助此數據,手機客戶端才能“定位”(這個詞不是特別貼切,看完后面的相信就可以明白了。)

驗證階段

然后手機客戶端,將客戶端上已經登錄的您的賬號,加上這個數據

手機端驗證

  • 如果在時效內確認,則會登陸成功。


    掃碼成功
  • 如果時效內未進行驗證,則二維碼失效。


    二維碼失效

如此將需要的數據進行打包,然后向服務器發送一個請求,然后服務器通過這個數據 定位到數據庫中相關的登錄表上,然后添加登陸的用戶的用戶名,確認登陸。然后登陸標記記為已登錄, 狀態。

成功登陸

好了,大致的整個流程就是這樣了,是不是很容易也可以理解呢。

準備

“工欲善其事,必先利其器”,所以咱們還是先著手搭建一個好用的環境吧。

搭建環境

可能每個人使用的軟件版本會有所不同,但是基本上都是可以正常工作的,如果您正確安裝了的話。 下面羅列一下我自己的環境。

服務器環境

  • PHP5.2.8
  • Apache2.2
  • MySQL5.7

第三方依賴

另外,本次試驗要完成的是掃碼登陸,所以必不可少的要生成二維碼。在PHP中生成二維碼的方式有很多,比較常用的是:

然后為了更加方便的進行HTML元素的操作,就把JQuery也拿過來好了。
不過這不是必須需要的,如果不想用,可以用原生的JavaScript來實現。
我用的是

jquery-2.2.4.min.js

后端

我感覺上面原理熟悉了之后,后臺設計就應該很簡單了。先來看看目錄結構吧(比較散亂,吸取教訓哈)。


目錄結構

數據庫

因為這次試驗主要是為了實現掃碼登陸,所以就直接設計一個登錄表好了,雖然實際中肯定不是這樣的。也比這要復雜的多。

登陸表設計

id就作為上面講述的那個特殊的數據
而創建時間createtime 則是為了時效。而存在。
其余字段不再過多解釋。

生成二維碼

借助PHP的QRCode庫,其實是很方便的。

<?php
    error_reporting(E_ALL);
    ini_set('error_reporting', '1');
session_start();
include "./phpqrcode/phpqrcode.php";

$value = uniqid();
$errorCorrectionLevel = "L";
$matrixPointSize = "4";

// session storage
$_SESSION['uuid'] = $value;
// 向數據庫中插入生成的數據
    $link = mysql_connect('localhost', 'root', 'root') or die(mysql_error());
    mysql_query('set names utf8');
    mysql_select_db('test');
    
    
    $createtime = date("Y-m-d H:i:s");
    $account = 'guest';
    $isscanned = 0;
    $issuccess = mysql_query("insert into qrcode values('$value', '$account', '$createtime', $isscanned)") or die(mysql_error());
    
    //var_dump($issuccess);
    

    if($issuccess==1){
        QRcode::png($value, false, $errorCorrectionLevel, $matrixPointSize);
    }else{
        echo "insert into db failed!";
    }

?>

雖然代碼中向數據庫中插入了游客賬號,但是這并不影響接下來客戶端發送請求后對登陸用戶及信息的更改。

然后需要注意的是記得在代碼的開始處開啟session,不然有可能會出錯。

處理確認登陸請求

處理登陸請求其實也算是重中之重了。所以handler.php的責任義不容辭。

<?php
    session_start();
    header("Content-Type: text/json;charset=UTF-8");

    $uuid = $_REQUEST['uuid'];
//  echo $uuid;
    
    // 獲取到數據庫中與此uuid一致的那一行的用戶信息
    $link = mysql_connect('localhost', 'root', 'root') or die(mysql_error());
    mysql_query('set names utf8');
    mysql_select_db('test');
    
    $resultset = mysql_query("select * from qrcode where id= '$uuid'") or die(mysql_error());
    while(($row=mysql_fetch_array($resultset))) {
        $result[] = $row; 
    }
    mysql_close($link);
    
    echo json_encode($result);

?>

至于作用嘛,就是網頁前臺那塊用于更改登陸者信息。使用ajax輪詢的方式對登錄表進行查詢,從而來實時的更新狀態信息。

ajax請求返回的結果

前端

好了,后臺已經搭建好了,這個時候就可以好好的寫寫前端的代碼了。我本人不太懂設計這塊,所以就簡單的寫了下,聊表心意算了。

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
        <title>二維碼掃描登陸</title>
        <style>
            .container {
                width: 600px;
                height: 480px;
                position: absolute;
                
                background: gray;               
                left: 50%;
                margin-left: -300px;
            }
            
            .header {
                width: 100%;
                height: 64px;
                position: relative;
                
                background: black;
            }
            
            .main {
                width: 80%;
                height: 340px;
                position: relative;
                
                left: 50%;
                margin-left: -30%;
                top: 12%;               
                
                background: url(921555.png) no-repeat;
                background-size: contain;
            }   
            
            ul {
                margin: 0px;
                padding: 0px;
                width: auto;
                list-style: none;
                
                position: relative;
            }
            ul >li {
                float: right;
                position: relative;
            }
            
            
            /*    設計顯示二維碼的空間*/
           .qrcontainer{
                width: 300px;
                height: 300px;
                top: 64px;
                
                position: relative;
                background: green;
           }
           .qrcontainer > img {
            width: 100%;
            height: 100%;
           }
            
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                
                <ul>
                    <font color="white" size="6" style="margin-top: 6px;">二維碼掃描登陸測試</font>
                    <li><font color="white" size="6"><a href="#">登陸</a>/&nbsp;<a href="#">注冊</a></font></li>
                </ul>
            </div>
            <div class="main">
                <img id="photo" src="" />
            </div>
        </div>
        
        <div class="qrcontainer">
            ![](./qrcode.php)
        </div>
        
        <input type="hidden" name="uuid" value="<?php session_start(); echo $_SESSION['uuid'];?>"/>
        
    </body>
    <script src="jquery-2.2.4.min.js"></script>
    <script>
        $(document).ready(function(){
            var uuid = document.getElementsByName('uuid')[0].value;
            // 想法是通過ajax輪詢,請求服務器上的登錄狀態信息
            $.ajax({
                url: './handler.php',
                type: 'POST',
                async: true,
                data: {
                    'uuid': uuid 
                },
                
                timeout: 5000,
                dataType: 'json',
                
                success: function(result){
                    document.getElementById("photo").src = 'photo.jpeg';
                    $(".qrcontainer").css('display', 'none');
                    console.log(result);
                },
                error: function(){
                    console.log('額,AJAX請求出錯了!');
                }
                
                
            });
            
            
        });
    </script>
    

</html>

效果

觀看完人家阿里云的,再來看咱自己的。額,瞬間感覺檔次下降了好多啊。

首頁

先來看看首頁效果圖


首頁

掃碼

掃碼這塊,我沒有另外寫一個app。其實原理了解了就行了。 App的作用就是將掃描到的二維碼的UUID值,加上用戶的用戶名等信息傳給服務器。

這個時候服務器就可以根據UUID查找到剛才插入到數據庫上的信息,然后進行信息的更新操作即可。操作比較簡單,這里就不再進行演示了。

前臺通過ajax請求就可以獲取到:是誰登陸了?這些信息。

這里通過添加一張圖片來驗證確實通過了驗證請求。

登陸成功,添加了一個頭像

查看一下后臺發送過來的數據,也可以進一步進行驗證的啦。


驗證后端發送過來的數據

拓展

基本上效果已經實現的差不多了。但是做的仍然不夠好。我覺得可以從下面幾個角度進行加強。

輪詢

上面的代碼沒有進行輪詢處理。其實完全可以設置一個Inerval來進行的。這樣才能更加逼真的體現實時性的特點。

超時

想必您也已經看到了數據庫中設計好的createtime字段。之所以設置這樣的一個字段,就是為了讓二維碼在一定是的時段內有效。這樣可以進一步加強登錄操作的安全性。

至于優化部分,使用JavaScript很容易啦。不過多敘述。

掃描后失效

這一點可以通過isscanned字段進行控制。當然了,離不開ajax的配合。通過對此字段的“監控”。就可以很容易的實現這一個效果。

總結

回顧一下本次實驗。主要是實現了一個非權威的掃碼登陸功能,(雛形一個)。

然后根據代碼本身,找到了幾個可以進行優化和拓展的方向。想來進一步的話,做成一個更加完善的掃碼登陸,也會水到渠成的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,099評論 25 708
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,123評論 6 13
  • 【很多年后,當我們再遇到自己初戀的那個人,會不會像林真心和徐太宇那樣會心一笑,然后道一句“好久不見”。但事實上,大...
    我超快樂的閱讀 150評論 0 5
  • 穿過巖洞凝望懸崖 愛情的尸骨千瘡百孔出現 你途經陸橋,走在白云中央 . 誰見證了海枯石爛 問嶼中的候鳥腳下的浪花 ...
    東山島高永川閱讀 457評論 0 4
  • 二零一一年三月十二日 天氣 Nice 今天因為有很多會議要召開分析新兵連的現實情況、安全系數、工作方向,重點...
    啊Ben閱讀 223評論 6 8