欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊


    自撰寫本文以來的幾年中,許多黑客攻擊已將目標鎖定在受密碼保護的網站上??蛻裘艽a的存儲已成為許多討論的主題,其中一些有用,而另一些則被誤導了。當然,沒有人會以明文形式存儲客戶端密碼,但是許多嘗試的解決方案(消息摘要,加密等)都比明文略好??稍诖颂幷业接嘘P密碼存儲的配套文章:PHP中的密碼哈希。以下討論和文章部分“后記:關于存儲密碼”已過時,不應用作您的應用程序的基礎。
    介紹
    對于新PHP開發人員來說,常見的設計模式問題是這樣的:“如何處理客戶端注冊和登錄?” 它在每個框架和CMS中都已完成,并且它們都使用類似的模式。本文逐步構建了模式,因此您可以查看代碼各部分的內容。
    對于此示例,我們依靠PHP會話處理程序來告訴我們客戶端是否已登錄。我們還使用cookie,以便“記住”客戶端已登錄,并且我們使用了包含客戶端的數據庫表信息。
    我們對這種設計模式的實現使我們能夠使用一行PHP代碼對網頁進行密碼保護,如下所示:

    access_control();
    


    此外,我們可以使用以下方法測試客戶端登錄(實際上不需要登錄):

    if (access_control(TRUE)) { /* CLIENT IS ALREADY LOGGED IN */ }
    



    本文結尾處有一些注釋和后記。如果有時間,您可能需要向下滾動并立即閱讀。當您嘗試使用此設計時,它們會更深入地介紹您可能遇到的問題。然后回來并繼續。
    約定和標準
    1.我們同意在所有頁面上都使用session_start()的約定,沒有例外。您可能希望將session_start()添加到通用腳本的頂部,該腳本會包含在所有頁面腳本的頂部,以便您網站的每個頁面都可以這樣開始:

    <?php 
    require_once('RAY_EE_config.php'); 
    // PHP AND HTML CODE FOLLOWS BELOW
    


    “ config”腳本也是放置數據庫連接和選擇代碼以及define()語句以及局部變量,類和函數的好地方,您可能已經知道要在一個數據庫中包含這些公共元素。單一,易于查找的腳本。
    2.我們同意這樣的約定:我們將access_control()語句添加到要保護的每個頁面的非常頂部。為什么要頂?因為我們可能需要使用header()函數,并且這是HTTP的協議限制,所以必須在所有瀏覽器輸出之前呈現并完成所有標頭。header()語句將失敗,并且如果違反此協議,則腳本將失敗。在創建瀏覽器輸出的同時,有多種方法可以遵循此協議。PHP函數ob_start()可以幫助您解決此問題。但是ob_start()對于這里的任務不是必需的-只有在完成所有標頭命令之后,我們才能以正確的順序處理數據并產生瀏覽器輸出(如果有)。有了這些了解之后,讓我們開始為訪問控制系統構建框架。
    通用元素-配置腳本
    第一步將是創建“配置”腳本,其中包含我們所有網頁腳本所需的通用元素。您將需要對這些示例進行一些自定義。特別是,您將要在下面的腳本的第15-20行附近添加自己的數據庫憑據。有了這些信息,您應該能夠將這些代碼片段中的每一個安裝在您自己的服務器上,并運行它們以查看實際的“移動部件”。
    有了數據庫憑證后,我們連接到數據庫服務器并選擇數據庫(第21-34行)。
    看一看在第36行定義的access_control()函數。它所做的第一件事是保存客戶端的入口點,以便我們在客戶端認證之后可以返回到正確的頁面。我們使用REQUEST_URI字符串而不是PHP_SELF,因為REQUEST_URI不僅包含我們的URL地址,還包含URL參數。PHP_SELF僅具有URL地址。接下來,我們測試會話UID變量。如果設置了此選項,則客戶端已經登錄,因此不需要進一步處理,并且我們返回TRUE。如果客戶端未登錄,則僅進入此函數的下一行。如果客戶端未登錄,則查看$ test參數。默認情況下,它設置為FALSE,但是如果調用腳本將其設置為TRUE,我們將返回一個指示信息,表明客戶端未登錄。如果客戶端未登錄,這不是測試,我們必須保護頁面。因此,我們將客戶端瀏覽器重定向到我們的登錄頁面并退出腳本。
    我們還需要一個函數來完成我們的工作-設置“記住我” cookie的函數。該定義從第53行開始。我們將Cookie的“ uuk”命名為“唯一用戶密鑰”,并將其生存期取決于在第10行定義的常數REMEMBER的定義。有關setcookie()的更多信息,請參見PHP在線手冊,位于:http : //php.net/manual/en/f unction.se tcookie.ph p
    有了“ config”框架,我們就可以通過執行從第80行開始的通用代碼來開始每個網頁。我們測試的第一件事是會話數組中是否存在“ uid”。如果有的話,我們就有一個經過身份驗證的客戶端,不需要其他處理。但是,如果未設置$ _SESSION [“ uid”],我們仍然可以通過“ uuk” cookie中的信息來記住該客戶端。如果設置了cookie,則我們可以在數據庫中查找客戶端并自動完成登錄,從而實現“記住我”的承諾。
    因為$ _COOKIE數組包含存儲在客戶端計算機上的數據,所以必須將其視為“污染的”外部數據。因此,最起碼的檢查是在查詢中使用mysqli :: real_escape_string ()之前運行數據。使用這樣準備的數據,我們可以查詢用戶表并嘗試查找與該唯一用戶密鑰匹配的UID。如果我們在數據庫中找到該UID,則將其復制到會話數組(第101行)中,并且客戶端現在已登錄。我們的最后一步是在第104行調用Remember_me()函數,從而擴展了該客戶端的內存。通過在此調用此功能,可以使被記住并經常訪問該站點的客戶得到反復記住,甚至永遠被記住。這是常見的“ config”腳本:

    <?php // RAY_EE_config.php
    
    // WHEN WE ARE DEBUGGING OUR CODE, WE WANT TO SEE ALL THE ERRORS!
    error_reporting(E_ALL);
    
    // REQUIRED FOR PHP 5.1+
    date_default_timezone_set('America/Chicago');
    
    // THE LIFE OF THE "REMEMBER ME" COOKIE
    define('REMEMBER', 60*60*24*7); // ONE WEEK IN SECONDS
    
    // WE WANT TO START THE SESSION ON EVERY PAGE
    session_start();
    
    // CONNECTION AND SELECTION VARIABLES FOR THE DATABASE
    $db_host="localhost"; // PROBABLY THIS IS OK
    $db_name="??";        // GET THESE FROM YOUR HOSTING COMPANY
    $db_user="??";
    $db_word="??";
    
    // OPEN A CONNECTION TO THE DATA BASE SERVER AND SELECT THE DB
    $mysqli=new mysqli($db_host, $db_user, $db_word, $db_name);
    
    // DID THE CONNECT/SELECT WORK OR FAIL?
    if ($mysqli->connect_errno)
    {
        $err="CONNECT FAIL: "
        . $mysqli->connect_errno
        . ' '
        . $mysqli->connect_error
        ;
        trigger_error($err, E_USER_ERROR);
    }
    
    // DEFINE THE ACCESS CONTROL FUNCTION
    function access_control($test=FALSE)
    {
        // REMEMBER HOW WE GOT HERE
        $_SESSION["entry_uri"]=$_SERVER["REQUEST_URI"];
    
        // IF THE UID IS SET, WE ARE LOGGED IN
        if (isset($_SESSION["uid"])) return $_SESSION["uid"];
    
        // IF WE ARE NOT LOGGED IN - RESPOND TO THE TEST REQUEST
        if ($test) return FALSE;
    
        // IF THIS IS NOT A TEST, REDIRECT TO CALL FOR A LOGIN
        header("Location: RAY_EE_login.php");
        exit;
    }
    
    // DEFINE THE "REMEMBER ME" COOKIE FUNCTION
    function remember_me($uuk)
    {
        // CONSTRUCT A "REMEMBER ME" COOKIE WITH THE UNIQUE USER KEY
        $cookie_name='uuk';
        $cookie_value=$uuk;
        $cookie_expires=time() + date('Z') + REMEMBER;
        $cookie_path='/';
        $cookie_domain=NULL;
        $cookie_secure=FALSE;
        $cookie_http=TRUE; // HIDE COOKIE FROM JAVASCRIPT (PHP 5.2+)
    
        // SEE http://php.net/manual/en/function.setcookie.php
        setcookie
        ( $cookie_name
        , $cookie_value
        , $cookie_expires
        , $cookie_path
        , $cookie_domain
        , $cookie_secure
        , $cookie_http
        )
        ;
    }
    
    
    // DETERMINE IF THE CLIENT IS ALREADY LOGGED IN BECAUSE OF THE SESSION ARRAY
    if (!isset($_SESSION["uid"]))
    {
    
        // DETERMINE IF THE CLIENT IS ALREADY LOGGED IN BECAUSE OF "REMEMBER ME" FEATURE
        if (isset($_COOKIE["uuk"]))
        {
            $uuk=$mysqli->real_escape_string($_COOKIE["uuk"]);
            $sql="SELECT uid FROM EE_userTable WHERE uuk='$uuk' LIMIT 1";
            $res=$mysqli->query($sql);
    
            // IF THE QUERY SUCCEEDED
            if ($res)
            {
                // THERE SHOULD BE ONE ROW
                $num=$res->num_rows;
                if ($num)
                {
                    // RETRIEVE THE ROW FROM THE QUERY RESULTS SET
                    $row=$res->fetch_assoc();
    
                    // STORE THE USER-ID IN THE SESSION ARRAY
                    $_SESSION["uid"]=$row["uid"];
    
                    // EXTEND THE "REMEMBER ME" COOKIE
                    remember_me($uuk);
                }
            }
        }
    }
    



    數據庫表-我們的客戶數據模型
    現在,我們已經創建了常見的“ config”腳本,是時候創建將有助于訪問控制功能的數據庫表了。下面“創建”代碼段中的這段代碼應該做得很好。EE_userTable包含三列。這些是“ uid”列中的用戶身份,“ pwd”列中的用戶密碼和“ uuk”列中的用戶唯一鍵。在現實生活中,我們永遠不會以明文形式存儲密碼;我們將存儲密碼的抽象或加密版本。(請參閱本文結尾處的后記)。但是對于此示例,如果我們以明文形式處理密碼,則可使設計更易于理解。

    <?php // RAY_EE_create.php
    require_once('RAY_EE_config.php');
    
    // ACTIVATE THIS TO DROP THE OLD EE_userTable
    // $mysqli->query("DROP TABLE EE_userTable");
    
    $sql="CREATE TABLE EE_userTable
    ( _key INT         NOT NULL AUTO_INCREMENT
    , uid  VARCHAR(16) NOT NULL DEFAULT '?'
    , pwd  VARCHAR(16) NOT NULL DEFAULT '?'
    , uuk  VARCHAR(32) NOT NULL DEFAULT '?'
    , PRIMARY KEY (_key)
    )
    "
    ;
    if (!$res=$mysqli->query($sql)) trigger_error( $mysqli->error, E_USER_ERROR );
    



    測試工具
    此時,最好為我們的新腳本和我們的新數據庫表創建測試平臺。我們將需要兩個腳本進行測試。一個將完全由訪問控制。另一個將是一個公共頁面,該頁面僅測試訪問控制并使用響應來確定要創建哪種輸出。這兩個腳本符合這些要求。

    <?php // RAY_EE_controlled.php
    require_once('RAY_EE_config.php');
    
    // ACCESS TO THIS PAGE IS CONTROLLED
    $uid=access_control();
    
    echo "<br/>HELLO $uid AND WELCOME TO THE ACCESS CONTROLLED PAGE";
    



    <?php // RAY_EE_public.php
    require_once('RAY_EE_config.php');
    
    // ACCESS TO THIS PAGE IS TESTED BUT NOT CONTROLLED
    if ($uid=access_control(TRUE))
    {
        echo "<br/>HELLO $uid AND WELCOME TO THE PUBLIC PAGE";
    }
    else
    {
        echo "<br/>HELLO STRANGER.";
        echo "<br/>YOU MIGHT WANT TO <a href=\"RAY_EE_register.php\">REGISTER</a> ON THIS SITE";
        echo "<br/>IF YOU ARE ALREADY REGISTERED, YOU CAN <a href=\"RAY_EE_login.php\">LOG IN HERE</a>";
    }
    



    方便客戶使用-注冊頁面
    如果我們只有幾個用戶,則可以使用phpMyAdmin手動注冊所有用戶,但是如果我們有一個面向公眾的網站,則將需要很多工作。相反,我們想要創建一個頁面,以便我們的用戶可以注冊自己。下面的頁面將為我們完成注冊工作。補充說明:如果您想稍微擴展一下這個概念,此處的EE文章可能對您有所幫助。
    HTTP://www.experts-exchang e.com/Web_發展噸/ Web_Lang uages-斯坦dards / PHP / A_3939-Reg中istration-和-的電子郵件- Confirmati上功能于PHP。html
    與我們所有的腳本一樣,此腳本以PHP命令開始,以第2行的方式加載“ config”腳本require_once('RAY_EE_confi g.php'),我們使用include()函數的require形式,因為腳本無法運行沒有我們的配置文件。我們使用include()函數的一次形式,因為配置文件包含函數定義,并且任何重新定義PHP函數的嘗試都將導致致命錯誤。
    要開始注冊過程,假設沒有錯誤,我們樂觀地將$ err變量設置為NULL(第5行)。我們稍后可以檢查它是否有任何錯誤。然后,我們查看$ _POST數組以查看是否擁有處理注冊所需的所有信息。如果我們還沒有注冊信息,該腳本將落到第53行,其中將顯示注冊表格。如果我們擁有表格中的所有注冊信息,我們可以嘗試創建客戶記錄。
    創建客戶記錄的第一步是努力清理外部輸入。除了這里的基礎知識,我們沒有做任何其他事情;在現實生活中,可能會有更廣泛的過濾和測試。但是對于此示例,我們只是通過轉義從表單輸入接收到的三個文本字段來保護數據庫。
    我們的第一個重要測試是查看兩個密碼字段是否匹配。我們這樣做是因為客戶端正在鍵入type=“ password”的表單輸入字段,并且瀏覽器將在輸入時掩蓋輸入內容。為了讓我們的客戶滿意,我們要求她輸入兩次密碼,然后檢查是否匹配。如果她以相同的方式兩次輸入密碼,我們可以肯定的是,打字錯誤不會導致將偽造的密碼分配給她的帳戶。如果不匹配,我們將錯誤消息附加到$ err變量。
    接下來,我們檢查數據庫以查看是否已使用UID。如果是這種情況,我們將其視為錯誤,并且將設置錯誤指示器的方式與設置密碼不匹配的錯誤指示器的方式相同-通過將錯誤消息添加到$ err變量的末尾。(您可能考慮使用UNIQUE標記MySQL表中的uid列。如果嘗試將重復的信息放入UNIQUE列中,MySQL將拋出錯誤#1062)。
    編輯完成后(第25行),我們將測試$ err值。由于使用PHP if()語句測試時,NULL字符串將返回FALSE,因此我們可以簡單地檢查$ err是否為空。我們使用PHP的“ not”表達式,即感嘆號。如果我們有錯誤,則該測試將失敗,代碼將下降至第48行,在此處顯示錯誤消息并再次出示注冊表格。如果沒有阻止注冊的錯誤,我們可以在第28行繼續進行處理。
    我們結合使用用戶ID,密碼和隨機數來創建一個完全唯一且不可預測的值。這是我們可以在cookie中使用的“唯一用戶密鑰”。為什么不只使用數據庫中的auto_increment鍵?因為Cookie中的可預測值會引起黑客入侵。例如,如果黑客看到其cookie值為“ 123”,則可能會嘗試將其cookie更改為“ 122”,然后看看會發生什么。當我們使用唯一數據組合的md5()哈希值時,我們很難猜測被黑客入侵的cookie中可能起作用的值。我們的查詢將用戶ID,密碼和唯一的用戶密鑰放入表中,并且我們的注冊已完成。
    我們的客戶現在可以登錄。但是,為什么要讓他們在注冊后分別登錄?僅需一行代碼(第33行),我們便可以在注冊時完成其登錄。我們一直希望對我們的客戶好!
    接下來,我們將注意力轉向客戶是否希望我們記住登錄狀態的問題。如果選中了“ rme”復選框,它將在$ POST數組中設置,我們可以對其進行測試以查看是否需要記住客戶端。(與type=“ text”的空輸入字段不同,未選中的type=“ checkbox”字段根本不會出現在$ _POST數組中)。因此,如果存在“ rme”,我們將調用Remember_me()函數并將其傳遞給唯一的用戶密鑰。如果沒有,我們將跳過此步驟,并且不會設置任何cookie?,F在我們的注冊和登錄工作已經完成,我們在第42行歡迎客戶并在第44行結束腳本。這是注冊腳本:

    <?php // RAY_EE_register.php
    require_once('RAY_EE_config.php');
    
    // WE ASSUME NO ERRORS OCCURRED
    $err=NULL;
    
    // WAS EVERYTHING WE NEED POSTED TO THIS SCRIPT?
    if ( (!empty($_POST["uid"])) && (!empty($_POST["pwd"])) && (!empty($_POST["vwd"])) )
    {
        // YES, WE HAVE THE POSTED DATA. ESCAPE IT FOR USE IN A QUERY
        $uid=$mysqli->real_escape_string($_POST["uid"]);
        $pwd=$mysqli->real_escape_string($_POST["pwd"]);
        $vwd=$mysqli->real_escape_string($_POST["vwd"]);
    
        // DO THE PASSWORDS MATCH?
        if ($pwd !=$vwd) $err .="<br/>FAIL: CHOOSE AND VERIFY PASSWORDS DO NOT MATCH";
    
        // DOES THE UID ALREADY EXIST?
        $sql="SELECT uid FROM EE_userTable WHERE uid='$uid' LIMIT 1";
        if (!$res=$mysqli->query($sql)) trigger_error( $mysqli->error, E_USER_ERROR );
        $num=$res->num_rows;
        if ($num) $err .="<br/>FAIL: UID $uid IS ALREADY TAKEN.  CHOOSE ANOTHER";
    
        // IF THERE WERE NO ERRORS THAT PREVENT REGISTRATION
        if (!$err)
        {
            // MAKE THE UNIQUE USER KEY
            $uuk=md5($uid . $pwd . rand());
            $sql="INSERT INTO EE_userTable (uid, pwd, uuk) VALUES ('$uid', '$pwd', '$uuk')";
            if (!$res=$mysqli->query($sql)) trigger_error( $mysqli->error, E_USER_ERROR );
    
            // STORE THE USER-ID IN THE SESSION ARRAY
            $_SESSION["uid"]=$uid;
    
            // IS THE "REMEMBER ME" CHECKBOX SET?
            if (isset($_POST["rme"]))
            {
                remember_me($uuk);
            }
    
            // REGISTRATION AND LOGIN COMPLETE
            echo "<br/>WELCOME $uid. REGISTRATION COMPLETE.  YOU ARE LOGGED IN.";
            echo "<br/>CLICK <a href=\"/\">HERE</a> TO GO TO THE HOME PAGE";
            die();
        }
    
        // IF THERE WERE ERRORS
        else
        {
            echo $err;
            echo "<br/>SORRY, REGISTRATION FAILED";
        }
    } // END OF FORM PROCESSING - PUT UP THE FORM
    ?>
    <form method="post">
    PLEASE REGISTER
    <br/>CHOOSE USERNAME: <input name="uid" />
    <br/>CHOOSE PASSWORD: <input name="pwd" type="password" />
    <br/>VERIFY PASSWORD: <input name="vwd" type="password" />
    <br/><input type="checkbox" name="rme" />KEEP ME LOGGED IN (DO NOT CHECK THIS ON A PUBLIC COMPUTER)
    <br/><input type="submit" value="REGISTER" />
    </form>
    



    客戶端身份驗證-登錄頁面
    現在我們可以注冊用戶,并且我們擁有測試頁面,可讓我們查看實際的注冊,我們需要創建登錄和注銷頁面。
    登錄頁面使用類似于注冊頁面的結構。我們需要我們的“配置”頁面,然后進行測試以查看是否提供了必要的憑據(第5行)。我們過濾并清理外部輸入(第8-9行),然后查詢數據庫,在UID和PWD字段(第12-20行)中查找完全匹配的一個。如果找不到在UID和PWD上都匹配的行,則第20行的if()語句將失敗,腳本將下降至第46行,在此我們可以告訴客戶端身份驗證失敗,并可以顯示登錄名再次形成。如果確實找到了要查找的一行,則檢索該行(第23行)并將UID值復制到會話數組(第26行)中,以顯示客戶端現在已登錄。我們的下一步是查看是否客戶選中了“記住我”框。我們測試該復選框(第29行),如果已選中該復選框,我們將調用Remember_me()函數,并傳遞在注冊時創建的唯一用戶密鑰。Remember_me()函數可在瀏覽器上設置一個長壽命的cookie。如果沒有此cookie,則僅使用會話cookie來記住客戶端。當瀏覽器窗口關閉時,會話cookie也會過期。
    登錄處理的最后一步是確定客戶端下一步要去哪里。我們通過測試會話數組中的“ entry_uri”來做到這一點。如果它是由配置腳本中的access_control()函數設置的,我們可以在header()命令中使用該地址將客戶端帶回到原始頁面。如果未設置該選項(如果客戶端直接進入登錄頁面,則會發生這種情況),我們可以改為重定向到主頁。
    也許應該不用說,但是我還是要說:不要在您的登錄腳本中放入access_control()函數,否則您的代碼可能會導致服務器循環!這是登錄腳本:

    <?php // RAY_EE_login.php
    require_once('RAY_EE_config.php');
    
    // WAS EVERYTHING WE NEED POSTED TO THIS SCRIPT?
    if ( (!empty($_POST["uid"])) && (!empty($_POST["pwd"])) )
    {
        // YES, WE HAVE THE POSTED DATA. ESCAPE IT FOR USE IN A QUERY
        $uid=$mysqli->real_escape_string($_POST["uid"]);
        $pwd=$mysqli->real_escape_string($_POST["pwd"]);
    
        // CONSTRUCT AND EXECUTE THE QUERY - COUNT THE NUMBER OF ROWS RETURNED
        $sql="SELECT uid, uuk FROM EE_userTable WHERE uid='$uid' AND pwd='$pwd' LIMIT 1";
        $res=$mysqli->query($sql);
    
        // IF THE QUERY FAILED, GIVE UP
        if (!$res) trigger_error( $mysqli->error, E_USER_ERROR );
    
        // THERE SHOULD BE ONE ROW IF THE VALIDATION WAS PROCESSED SUCCESSFULLY
        $num=$res->num_rows;
        if ($num)
        {
            // RETRIEVE THE ROW FROM THE QUERY RESULTS SET
            $row=$res->fetch_assoc();
    
            // STORE THE USER-ID IN THE SESSION ARRAY
            $_SESSION["uid"]=$row["uid"];
    
            // IS THE "REMEMBER ME" CHECKBOX SET?
            if (isset($_POST["rme"]))
            {
                remember_me($row["uuk"]);
            }
    
            // REDIRECT TO THE ENTRY PAGE OR TO THE HOME PAGE
            if (isset($_SESSION["entry_uri"]))
            {
                header("Location: {$_SESSION["entry_uri"]}");
                exit;
            }
            else
            {
                header("Location: /");
                exit;
            }
        } // END OF SUCCESSFUL VALIDATION
        else
        {
            echo "SORRY, VALIDATION FAILED USING $uid AND $pwd \n";
        }
    } // END OF FORM PROCESSING - PUT UP THE LOGIN FORM
    ?>
    <form method="post">
    PLEASE LOG IN
    <br/>UID: <input name="uid" />
    <br/>PWD: <input name="pwd" type="password" />
    <br/><input type="checkbox" name="rme" />KEEP ME LOGGED IN (DO NOT CHECK THIS ON A PUBLIC COMPUTER)
    <br/><input type="submit" value="LOGIN" />
    </form>
    



    客戶端取消身份驗證-退出頁面
    如果我們的客戶端登錄,并且未選中“記住我”框,則當瀏覽器窗口關閉或會話垃圾收集例程檢測到長時間不活動時,他將自動注銷。 (通常約24分鐘)。但是,我們的客戶可能希望刻意注銷,或者可能是在謹慎的情況下在公共計算機上注銷。因此,我們還必須提供一個注銷腳本,如下所示。
    與往常一樣,我們的第一步是加載“ config”腳本。接下來,我們從會話數組中收集UID,或設置一個替代值。我們將在“再見”消息中使用此消息,因此,即使客戶端連續兩次登錄注銷腳本,或者試圖以某種方式在客戶端未登錄時設法去到那里,我們都嘗試選擇一個有意義的數據字符串這是在三元運算符語句(第5行)中完成的。
    我們處理“記住我” cookie(如果有的話)(第7-12行)。
    下一步是清除會話數組(第15行)。這可能看起來有些束手無策,您可能會考慮完全消除該會話是否有意義。如果即使在客戶端注銷后,會話中仍有其他信息要保留,則可以僅在第15行取消設置($ _SESSION [“ uid”])并跳過其余代碼。但是,您永遠不要使用unset($ _ SESSION)清除數組。請參閱此處的注意事項:
    http : //php.net/manual/en/s ession.exa mples.basi c.php
    最后,您可以使用我們在第5行創建的數據字符串說“再見”。瀏覽器輸出,而是激活標題(“位置:/”
    看一下“出口”;最后一行的聲明。盡管這里并不是嚴格要求的,但是在標題(“ Location”)語句之后使用“ exit”是一種養成的好習慣。為什么?因為您的腳本在發送header()之后將繼續正常運行,并且將運行一段不可預知的時間-直到瀏覽器收到該標頭并通過重定向停止腳本。有很多適當的header()語句可以作為完整腳本的一部分內聯使用,但是當您使用旨在作為腳本中最后一條語句的語句時,則需要采取額外的步驟來確保它是,實際上是最后一條要執行的語句。這是注銷腳本:

    <?php // RAY_EE_logout.php
    require_once('RAY_EE_config.php');
    
    // GRAB THE UID OR A CONSTANT FOR THE GOODBYE MESSAGE
    $uid=(isset($_SESSION["uid"])) ? ', ' . $_SESSION["uid"] : ' NOW';
    
    // IF THE "REMEMBER ME" COOKIE IS SET, FORCE IT TO EXPIRE
    $cookie_expires=time() - date('Z') - REMEMBER;
    if (isset($_COOKIE["uuk"]))
    {
       setcookie("uuk", '', $cookie_expires, '/');
    }
    
    // CLEAR THE INFORMATION FROM THE $_SESSION ARRAY
    $_SESSION=array();
    
    // IF THE SESSION IS KEPT IN COOKIE, FORCE SESSION COOKIE TO EXPIRE
    if (isset($_COOKIE[session_name()]))
    {
       setcookie(session_name(), '', $cookie_expires, '/');
    }
    
    // TELL PHP TO ELIMINATE THE SESSION
    session_destroy();
    session_write_close();
    
    // SAY GOODBYE...
    echo "YOU ARE LOGGED OUT$uid.  GOODBYE.";
    
    // OR REMOVE THE GOODBYE MESSAGE AND ACTIVATE THESE LINES TO REDIRECT TO THE HOME PAGE
    // header("Location: /");
    // exit;
    



    客戶安全-密碼頁面
    我們都知道我們應該不時更改密碼。為客戶提供這種功能非常容易。與注冊頁面在設計上相似,密碼頁面采用一對新密碼,檢查是否匹配并更新數據庫以存儲新密碼。但是有一些重要的區別。
    每當我們更改數據模型中的某些內容時,我們都需要重新驗證客戶的密碼。為什么?因為我們都是人類,所以我們可能會不小心使計算機保持登錄狀態。一個偷偷摸摸的人可能會在我們不查看時嘗試更改我們的密碼(或其他信息)。為了減少這種風險,我們使用與現代ATM控制臺所使用的設計模式相似的設計模式。在每次提款之前,您必須重新輸入PIN碼。這是一個小麻煩,也是一種強大的安全措施。因此,我們將在“更改密碼”腳本中執行相同的操作。每當我們更改客戶記錄中的重要內容(例如電子郵件地址或送貨地址)時,我們都將使用此設計模式。
    我們的第一步是加載“ config”腳本,并調用訪問控制功能以檢索客戶端uid。我們假設沒有發生錯誤(第8行)。我們要求客戶端提供三項信息-舊密碼和新密碼,鍵入兩次以確保正確鍵入新密碼。如果我們擁有所有這三個條件(第11行),則可以開始處理請求。
    我們清理在查詢中使用的值(第14-17行)。接下來,我們測試兩個密碼字段是否匹配。我們這樣做是因為客戶端正在鍵入type=“ password”的表單輸入字段,并且瀏覽器將在輸入時掩蓋輸入內容。為了使我們的客戶滿意,我們要求她兩次輸入密碼,然后檢查是否匹配(第20行)。如果不匹配,我們將錯誤消息附加到$ err變量。
    接下來,我們檢查數據庫,以確保UID記錄與舊密碼一起存在。用戶表中應該只有這樣一行。如果不是這種情況,我們將其視為錯誤,并以與為密碼不匹配設置錯誤指示符相同的方式設置錯誤指示符(第26行)-通過將錯誤消息添加到密碼末尾$ err變量。
    編輯完成后(第29行),我們將測試$ err值。如果我們有錯誤,則該測試將失敗,代碼將下降至第42行,在此處顯示錯誤消息并再次顯示密碼表單。如果沒有阻止密碼更改的錯誤,我們可以在第32行繼續進行處理。
    請注意,第32行的UPDATE查詢中的WHERE子句–與我們在第23行的SELECT查詢中使用的WHERE子句完全相同。我們已經知道只有一行滿足該WHERE子句。因此,我們確定將使用新密碼更新正確的行。為了表示MySQL的性能,我們告訴數據庫限制為一行。這避免了表掃描。更新匹配行后,MySQL將在知道其工作完成后停止運行。
    密碼更改完成,我們向客戶發送成功消息(第36行)。如果您的實際實現在用戶表中有客戶的電子郵件地址(幾乎可以肯定),那么您可以擴展此地址以向她發送有關密碼更改的電子郵件。良好的安全做法會阻止您發送實際密碼。

    <?php // RAY_EE_password.php
    require_once('RAY_EE_config.php');
    
    // ACCESS TO THIS PAGE IS CONTROLLED
    $uid=access_control();
    
    // WE ASSUME NO ERRORS OCCURRED
    $err=NULL;
    
    // WAS EVERYTHING WE NEED POSTED TO THIS SCRIPT?
    if ( (!empty($_POST["old"])) && (!empty($_POST["pwd"])) && (!empty($_POST["vwd"])) )
    {
        // YES, WE HAVE THE NEEDED DATA. ESCAPE IT FOR USE IN A QUERY
        $uid=$mysqli->real_escape_string($uid);
        $old=$mysqli->real_escape_string($_POST["old"]);
        $pwd=$mysqli->real_escape_string($_POST["pwd"]);
        $vwd=$mysqli->real_escape_string($_POST["vwd"]);
    
        // DO THE PASSWORDS MATCH?
        if ($pwd !=$vwd) $err .="<br/>FAIL: CHOOSE AND VERIFY PASSWORDS DO NOT MATCH";
    
        // DOES THE UID AND OLD PASSWORD COMBINATION EXIST?
        $sql="SELECT uid FROM EE_userTable WHERE uid='$uid' AND pwd='$old' LIMIT 1";
        if (!$res=$mysqli->query($sql)) trigger_error( $mysqli->error, E_USER_ERROR );
        $num=$res->num_rows;
        if ($num !=1) $err .="<br/>FAIL: $uid DOES NOT HAVE PASSWORD $old";
    
        // IF THERE WERE NO ERRORS TO PREVENT THE PASSWORD CHANGE
        if (!$err)
        {
            // UPDATE THE TABLE TO CHANGE THE PASSWORD
            $sql="UPDATE EE_userTable SET pwd='$pwd' WHERE uid='$uid' AND pwd='$old' LIMIT 1";
            if (!$res=$mysqli->query($sql)) trigger_error( $mysqli->error, E_USER_ERROR );
    
            // PASSWORD CHANGE IS COMPLETE
            echo "<br/>THANK YOU, $uid. PASSWORD CHANGE IS COMPLETE.";
            echo "<br/>CLICK <a href=\"/\">HERE</a> TO GO TO THE HOME PAGE";
            die();
        }
    
        // IF THERE WERE ERRORS
        else
        {
            echo $err;
            echo "<br/>SORRY, PASSWORD CHANGE FAILED";
        }
    } // END OF FORM PROCESSING - PUT UP THE FORM
    ?>
    <form method="post">
    CHANGE YOUR PASSWORD
    <br/>FORMER PASSWORD: <input name="old" type="password" />
    <br/>CHOOSE PASSWORD: <input name="pwd" type="password" />
    <br/>VERIFY PASSWORD: <input name="vwd" type="password" />
    <br/><input type="submit" value="CHANGE" />
    </form>
    



    簡介-付諸實踐
    這就是使用基本的PHP身份驗證來密碼保護網頁的所有步驟。一旦有了這種結構,就可以顯示公共注冊和登錄頁面,并通過公共,受保護和部分受保護的網頁的組合來構建站點。最重要的是,您可以使用一行PHP代碼進行身份驗證測試。這些腳本使用PHP會話來標識已登錄的客戶端??蛻艨梢砸竽木W站記住他們的狀態,您可以幫他們。他們可以隨時注銷,也可以在一段時間不活動后自動注銷。他們可以隨時更改密碼來保護自己的帳戶信息。
    此處的注釋和代碼將在大多數PHP安裝中正常運行,但是它們僅作為教學示例,并不打算在生產環境中“按原樣”使用-因此,請隨意復制和修改它們以適合您的特定需求。
    后記:了解PHP會話
    盡管這些腳本以合理的方式使用PHP會話,但我發現很容易過分思考PHP會話的工作方式。它們比您預期的要容易得多!您可能需要閱讀這兩篇文章,以更好地了解我們的PHP客戶端身份驗證所依賴的基礎技術。
    關于PHP會話的文章。
    有關 HTTP客戶端/服務器協議的文章。
    后記:防止自動注冊
    曾經想知道在線論壇如何獲得這么多垃圾的偉哥廣告嗎?廣告由“攻擊”機器人腳本放置,這些腳本會找到注冊表格并注冊一個帳戶,然后使用該帳戶發布不需要的材料。結合使用兩種技術可以減少這種入侵的風險。首先是在注冊表上使用CAPTCHA測試。第二個是使用“握手”,這需要一個額外的步驟來通過電子郵件中的說明確認注冊。這兩種方法都可以單獨有效。綜合起來,它們甚至更有效。
    后記:MySQL和MySQL i (2014年春季)
    本文最初寫于幾年前,當時PHP支持MySQL數據庫擴展。此后發生了變化,如果您使用本文的舊版本作為指導,則可能需要更改腳本。幸運的是,如果選擇面向對象的MySQL i,則更改非常容易完成。要了解PHP為什么取消MySQL支持,以及如何使腳本保持運行狀態,請參閱這篇文章,該文章教您如何將過程式MySQL代碼轉換為MySQL i或PDO。
    后記:PHP session_unregister() (2014年秋季)
    一些過時的代碼集包含使用session_unregister()函數的“注銷”示例。PHP在很多年前不推薦使用此功能,而在最近將其刪除。不幸的是,PHP代碼示例沒有到期日期,因此您可能會遇到沒有任何警告標簽的過時代碼。如果您有一個使用session_unregister()的腳本,則應使用相同的函數調用參數將函數名稱替換為unset()。今后,請勿使用session_unregister(),session_register()或session_is_registered()。要了解本文的其余部分,您可能想刷新有關PHP會話如何工作的記憶。
    后記:關于存儲密碼
    實際上,您不會以明文形式存儲客戶端密碼。您可以使用PHP md5()函數對密碼進行編碼。 MD5是“消息摘要”的縮寫。請在這里閱讀評論。我不同意這樣的觀念,即如果您了解自己在做什么并且正確使用md5(),那么md5()哈希對于大多數用例來說是不夠的。但是,許多專家贊成使用密碼哈希?;蛑辽偈羌用堋_@是我對md5()的看法。
    1.假設您愚蠢地以明文形式存儲了客戶端密碼。優點:當客戶端忘記密碼時,腳本可以發送客戶端密碼。缺點:如果您的數據庫遭到破壞,則將公開所有客戶端密碼。
    2.假設您沒有存儲明文密碼,但是卻愚蠢地存儲了密碼的md5()摘要。看起來像這樣...
    5f4dcc3b5aa765d61d8327deb8 82cf99
    ...這是“密碼”的md5()。您不能僅通過查看就容易判斷出此md5()字符串與“ password”匹配,但是md5()摘要的問題在于它們在編程上是冪等的。無論您對“密碼”進行散列多少次,都將始終獲得相同的md5()字符串。如果兩個人選擇相同的密碼,則md5()字符串將相同。黑客知道最受歡迎的密碼md5()字符串,因此,如果您的數據庫遭到破壞,則會暴露許多客戶端密碼。黑客知道多少個普通密碼?您會相信數百萬嗎?你最好相信它!
    3.如果讓客戶選擇他們自己的密碼,而其中一個選擇“密碼”,則黑客更有可能破譯其他常用密碼。與流行密碼的md5()字符串匹配的暴力破解方法在計算上是微不足道的。每個字典單詞與其md5()摘要匹配最多需要幾秒鐘。
    4.為了使密碼更難破解,一個子行業涌現出了各種各樣的伏都教徒和關于密碼學的廢話。您可以避免廢話,并從OWASP項目中了解更多信息。您可以使用密碼哈希來增強密碼安全性。
    5.因為md5()是冪等的,所以安全性要求必須采取某些措施來破壞“密碼”和5f4dcc3b5aa765d61d8327deb8 82cf99之間的直接鏈接。那是在編碼過程中添加到密碼的“鹽”。在密碼后面附加一個鹽字符串,冪等關系不僅需要密碼,還需要鹽。因此,如果客戶端選擇“密碼”,則服務器將存儲諸如“密碼XYZ ”之類的md5字符串,其結果摘要為cceef54fde042f058f57108433 8e2c40。比較這些md5字符串,看看是否可以看到關系。我不能
    6.您的鹽不必很容易猜測。但是必須將其存儲在某個位置,以使其在腳本執行期間可以編程方式供PHP使用。您可能要小心保護它。如果鹽析字符串和算法遭到破壞,則可能暴露您客戶的密碼。也許您想將其放入存儲在WWW根目錄上方的PHP腳本中,并通過include()函數將其引入Web根腳本的范圍。
    7.您可以在密碼的兩端加鹽加鹽胡椒粉))。您可以使用非常長且任意的字符串來放入鹽和胡椒。只要將相同的鹽和胡椒粉添加到客戶端輸入密碼框中的任何內容,您的md5()算法就會創建冪等消息摘要。您可以使用簡單的SQL查詢來匹配密碼。
    8. md5()沖突的可能性(兩個不同的輸入字符串匹配相同的消息摘要)與您的DNA序列遇到其他人的可能性幾乎相同。從理論上講這是可能的,但不要打賭。
    9.加鹽的密碼有多堅固?我將向任何人買啤酒,誰能告訴我創建此md5()摘要的原始輸入字符串:
    e0f1299ed629d3c8826e2dd2be 4780cf
    為了方便您搜索原始輸入字符串,這里是md5()算法說明的鏈接。
    http://www.faqs.org/rfcs/r fc1321.htm l
    并且我已經在服務器上安裝了此易于使用的腳本。在此處進行實驗:
    http : //www.iconoun.com/dem o / md5.php
    10.如果您選擇了好的鹽和胡椒粉字符串并將其保密,則在大多數情況下,您的md5()摘要將足以保護客戶端密碼。但是你不能解決愚蠢的問題。如果客戶選擇“密碼”,而您的登錄過程僅需要一個電子郵件地址和密碼,則沒有太多保護該客戶免于暴露的機會。內部如何對“密碼”進行編碼并不重要。知道站點中電子郵件地址的任何人都可以嘗試將每個人與“密碼”或其他常用密碼配對,以查看配對是否有效。毫無疑問,如果您的人口足夠多,則您的客戶社區中會有人使用“密碼”,并且她將成為任何攻擊的首批受害者之一。
    11.由于第10個原因,某些密碼選擇過程要求您使用字母和數字的組合,使用大寫和小寫等。我覺得這些令人討厭,并且傾向于使用多字密碼短語的概念。而不是一個密碼。我敢肯定會有流行和常用的詞組,并且明智的選擇是在詞組中選擇隨機單詞,并包含一些甚至根本不是單詞的內容。高鹽短語至少與高鹽密碼一樣好。
    12. md5()字符串始終為32個字符的十六進制數字,無論輸入字符串包含什么內容。因此,數據庫存儲必須具有32字節的列寬。ArsTechnica的
    這篇文章提供了內部人士對黑客可能如何攻擊您的編碼密碼的看法。最終,您的密碼就像是防火保險箱的門。根據時間和溫度對它們進行評級。堅固的門意味著您有更多的時間來焚燒物品。不幸的是,像ArsTechnica所做的那樣,每一項練習都將基本密碼和密碼短語添加到字典中,并且字典攻擊是最快成功的。
    而您要保護的內容至關重要。如果您有保齡球得分,購買歷史,醫療記錄,財務細節或核發射代碼,則安全措施可能會有所不同。

    PHP 5.3

    • 添加了命名空間的支持.

    • 添加了靜態晚綁定支持.

    • 添加了跳標簽支持.

    • 添加了原生的閉包(Lambda/匿名函數)支持.

    • 新增了兩個魔術方法, __callStatic 和 __invoke.

    • 添加了 Nowdoc 語法支持, 類似于 Heredoc 語法, 但是包含單引號.

    • 使用 Heredoc 來初始化靜態變量和類屬性/常量變為可能.

    • 可使用雙引號聲明 Heredoc, 補充了 Nowdoc 語法.

    • 可在類外部使用 const 關鍵詞聲明 常量.

    • 三元運算操作符有了簡寫形式: ?:.

    • HTTP 流包裹器將從 200 到 399 全部的狀態碼都視為成功。

    • 動態訪問靜態方法變為可能.

    • 異??梢员粌惹?

    • 新增了循環引用的垃圾回收器并且默認是開啟的.

    • mail() 現在支持郵件發送日志. (注意: 僅支持通過該函數發送的郵件.)

    PHP 5.4

    • 新增支持 traits 。

    • 新增短數組語法,比如 $a=[1, 2, 3, 4]; 或 $a=['one'=> 1, 'two'=> 2, 'three'=> 3, 'four'=> 4]; 。

    • 新增支持對函數返回數組的成員訪問解析,例如 foo()[0] 。

    • 現在 閉包 支持 $this 。

    • 現在不管是否設置 short_open_tag php.ini 選項,<?=將總是可用。

    • 新增在實例化時訪問類成員,例如: (new Foo)->bar() 。

    • 現在支持 Class::{expr}() 語法。

    • 新增二進制直接量,例如:0b001001101 。

    • 改進解析錯誤信息和不兼容參數的警告。

    • SESSION 擴展現在能追蹤文件的 上傳進度 。

    • 內置用于開發的 CLI 模式的 web server 。

    PHP5.5

    • 新增 Generators

    • 新增 finally 關鍵字

    • foreach 現在支持 list()

    • empty() 支持任意表達式

    • array and string literal dereferencing ?

    • 新的密碼哈希 API

    • 改進 GD

    PHP5.6

    • 使用表達式定義常量

    • 使用 ... 運算符定義變長參數函數

    • 使用 ... 運算符進行參數展開

    • 使用 ** 進行冪運算

    • use function 以及 use const

    • phpdbg

    • 默認字符編碼

    • php://input 是可重用的了

    • 大文件上傳(現在可以支持大于 2GB 的文件上傳)

    • GMP 支持運算符重載

    • 使用 hash_equals() 比較字符串避免時序攻擊

    • __debugInfo()

    • gost-crypto 散列算法

    • SSL/TLS 提升

    • pgsql 異步支持

    PHP7.0

    • 標量類型聲明

    • 返回值類型聲明

    • null合并運算符

    • 太空船操作符(組合比較符)

    • 通過 define() 定義常量數組

    • 匿名類

    • Unicode codepoint 轉譯語法

    • Closure::call()

    • 為unserialize()提供過濾

    • IntlChar

    • 預期

    • Group use declarations

    • 生成器可以返回表達式

    • Generator delegation

    • 整數除法函數 intdiv()

    • 會話選項

    • preg_replace_callback_array()

    • CSPRNG Functions

    • 可以使用 list() 函數來展開實現了 ArrayAccess 接口的對象

    • 其他特性

    PHP7.1

    • 可為空(Nullable)類型

    • Void 函數

    • Symmetric array destructuring

    • 類常量可見性

    • iterable 偽類

    • 多異常捕獲處理

    • list()現在支持鍵名

    • 支持為負的字符串偏移量

    • ext/openssl 支持 AEAD

    • 通過 Closure::fromCallable() 將callables轉為閉包

    • 異步信號處理

    • HTTP/2 server push support in ext/curl

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有