国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

一個完整、安全的用戶登錄系統

2024-05-04 23:04:13
字體:
來源:轉載
供稿:網友

  在使用php編程的時候,我有一個習慣,不太喜歡使用現成的庫文件,例如phplib或者其它類似的庫,在這個系統中,我也打算自己寫一個庫文件,它需要處理認證、確認email,更新帳號(密碼,email)等事情。
為了在保證該系統安全的同時,不會加重我現有數據庫的負擔。因此這個新的系統要依賴cookies。這確實是一個兩難的選擇,因為如果只是設置一個用戶名的cookie,是很不安全的,這行不通,但從數據庫的負擔考慮,我也不能加入一個簡單的無序碼而交由我的數據庫來進行驗證。

  解決的方法是同時設置兩個cookie,一個是用戶名的cookie,一個是無序碼的cookie。這個無序碼實際上是由用戶名和一個超級密碼(只有程序設計者知道)組合通過md5()函數運算產生的。由于md5()是一個單向的無序碼,因此是不可以破解的。在用戶更改email時,我也可以用該email和超級密碼產生一個無序碼,以讓用戶確認修改。這實際上是一個公匙/私匙類的系統。不明白?不要緊,下面再慢慢說明。

  有趣的是,這個系統的擴展能力是可以達到無窮的,因為該系統的主要工作是計算md5()函數的值,而且由web服務器完成,在負載增加時,可以加入其它的服務器來分擔負載,雖然認證系統不會拖跨一個數據庫,但是這樣做就讓最終的瓶頸只能出現在數據庫上。

  以下是該庫中的兩個函數--記號產生和記號認證函數。

  <?php

   $hidden_hash_var='your_secret_password_here';

   $logged_in=false;
   unset($logged_in);

   function user_isloggedin() {
    global $user_name,$id_hash,$hidden_hash_var,$logged_in;
    file://已經進行無序碼的檢測了嗎

    file://如果是的話,返回該變量

    if ( isset($logged_in) ) {

     return $logged_in;

     }

    file://are both cookies present?

    if ($user_name && $id_hash) {

    /*

     由cookies中得來的用戶名和系統超級密碼產生一個認證用的無序碼如果該無序碼與cookie中的無序碼一樣,則cookies中的變量是可信的,用戶已經登錄

    */

     $hash=md5($user_name.$hidden_hash_var);

     if ($hash == $id_hash) {

      file://無序碼符合,設置一個全局變量,這樣我們在再次調用該函數的時候

      file://就無需再次進行md5()運算

      $logged_in=true;

      return true;

     } else {

      file://兩個無序碼不符合,沒有登錄

      $logged_in=false;

      return false;

     }

     } else {

       $logged_in=false;

       return false;

      }

     }

   function user_set_tokens($user_name_in) {

    /*

     一旦用戶名和密碼通過驗證,就調用這個函數

    */

    global $hidden_hash_var,$user_name,$id_hash;

     if (!$user_name_in) {

      $feedback .= ' error - user name missing when setting tokens ';

      return false;

      }

    $user_name=strtolower($user_name_in);

     file://使用用戶名和超級密碼創建一個無序碼,作判斷是否已經登錄用

     $id_hash= md5($user_name.$hidden_hash_var);

     file://設置cookies的有效期為一個月,可設置為任何的值

     setcookie('user_name',$user_name,(time()+2592000),'/','',0);

     setcookie('id_hash',$id_hash,(time()+2592000),'/','',0);

    }

  ?>

再來看另一段有趣的代碼,用戶怎樣才能安全地改變他們的email地址呢?他們可以在任何時候改變email地址,但是要進行確認。

  <?php

    function user_change_email ($password1,$new_email,$user_name) {

     global $feedback,$hidden_hash_var;

     if (validate_email($new_email)) {

       $hash=md5($new_email.$hidden_hash_var);

       file://改變數據庫中確認用的無序碼值,但不改變email

       file://發出一個帶有新認證碼的確認email

       $user_name=strtolower($user_name);

       $password1=strtolower($password1);

       $sql="update user set confirm_hash='$hash' where user_name='$user_name' and password='". md5($password1) ."'";

       $result=db_query($sql);

       if (!$result || db_affected_rows($result) < 1) {

        $feedback .= ' error - incorrect user name or password ';

        return false;

        } else {

         $feedback .= ' confirmation sent ';

         user_send_confirm_email($new_email,$hash);

         return true;

         }

       } else {

         $feedback .= ' new email address appears invalid ';

         return false;

        }

       }

    function user_confirm($hash,$email) {

      /*

       用戶點擊認證email的相關連接時,連到一個確認的頁面,該頁面會調用這個函數,

      */

     global $feedback,$hidden_hash_var;

      file://verify that they didn't tamper with the email address

      $new_hash=md5($email.$hidden_hash_var);

      if ($new_hash && ($new_hash==$hash)) {

        file://在數據庫中找出這個記錄

        $sql="select * from user where confirm_hash='$hash'";

        $result=db_query($sql);

        if (!$result || db_numrows($result) < 1) {

          $feedback .= ' error - hash not found ';

          return false;

        } else {

          file://確認email,并且設置帳號為已經激活

          $feedback .= ' user account updated - you are now logged in ';

          user_set_tokens(db_result($result,0,'user_name'));

          $sql="update user set email='$email',is_confirmed='1' where confirm_hash='$hash'";

          $result=db_query($sql);

          return true;

         }

        } else {

         $feedback .= ' hash invalid - update failed ';

         return false;

        }

       }

    function user_send_confirm_email($email,$hash) {

      /*

       這個函數在首次注冊或者改變email地址時使用

      */

       $message = "thank you for registering at company.com".

       "/nsimply follow this link to confirm your registration: ".
       "/n/nhttp://www.company.com/account/confirm.php?hash=$hash&email=". urlencode($email). "/n/nonce you confirm, you can use the services on phpbuilder.";
mail ($email,'registration confirmation',$message,'from: [email protected]');

      }

    ?>


  評論:或許我們在用戶認證方面不是采用這種方法,而是采用session等方式,不過這篇文章在如何進行加密和確認方面,還是對我們有所啟發的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 霍州市| 南漳县| 门源| 莱州市| 靖远县| 襄汾县| 斗六市| 新泰市| 安康市| 宣武区| 潍坊市| 北安市| 绍兴市| 泰来县| 安泽县| 潮州市| 长汀县| 屏边| 永兴县| 保亭| 云霄县| 夏河县| 漠河县| 周宁县| 玉环县| 宜昌市| 红原县| 陆河县| 嵩明县| 新乡县| 积石山| 长垣县| 克拉玛依市| 祁阳县| 霍林郭勒市| 商洛市| 射洪县| 沙湾县| 成安县| 酉阳| 叙永县|