php建表管理、發送url實現會員找回密碼功能

來源:互聯網
上載者:User

    大多數的網站都有使用者註冊一項,使用者註冊後忘記密碼也是常有的事,所以都要有“找回密碼”這一功能。常用的“找回密碼”通常有郵箱找回密碼和簡訊找回密碼兩種,這裡只討論通過發郵件實現“找回密碼”功能。如何通過指令碼發郵件,先前寫的文章有介紹《windows下使用php內建的mail函數實現簡單郵件發送執行個體》。

    使用者通過填寫使用者名稱或使用者ID以及之前註冊時填寫的郵箱,申請找回密碼。我們知道,網站的使用者資訊表中的密碼欄位,是經過加密,並且是無法復原(也就是說即使是管理員開啟這張表,也看不出密碼是什麼,防止資訊表被盜以致使用者資訊泄露),也就是說使用者申請找回密碼其實是找不回來原密碼的,我們要做的是隨機產生一個新的密碼發至使用者郵箱,讓使用者儘快登陸修改密碼。以上過程看似很簡單,其實還是有很多注意的地方。

    一、如果有些懷有惡意的人知道了別人的使用者名稱和郵箱,如果我們“找回密碼”的實現是一有這樣的提交就馬上重設密碼發至使用者郵箱,那就會造成惡意破壞,鄙人雖然智商不高,但這樣的辦法是想都不敢想的。

    二、如一所述,我們在接到“找回密碼”申請時,發至使用者郵箱的應該是一條確認連結,只有使用者登入郵箱點選連結確認後,我們才會重設密碼,提醒使用者及時修改。至於這條連結,也就是url該怎麼構造,才能確認這是我們發出去的url,總不能這條url被心懷不軌之人隨便一改,我們就得重設密碼吧。網上關於這一點,主要有兩個爭論,就是要不要建立一個找回密碼錶管理url。

        1、不用建表

           直接構造url。url=findPwd?id=使用者ID&email=郵箱&confirmCode=確認碼。這個確認碼可以是(使用者ID+原密碼+郵箱等)加密而成,只要你能收到這個url後,根據類似使用者ID和郵箱資訊查詢使用者資訊表,讀取事先預定的欄位(也就是構造確認碼所需欄位)重新構造確認碼,與接收到的確認碼進行對比,正確則重設密碼,失敗則說明這不是我們發出去的url。有些人說這個確認碼可以加一個隨機欄位更安全,如"確認碼=加密(使用者ID+原密碼+郵+time())",只是我想不來,如果沒有儲存這個確認碼或者這個隨機欄位,當我們再次構造確認碼與接收到的確認碼對比時,該如何構造。

        2、建表

        表結構大致如下

        id    cteateTime(建立時間)    confirmCode(確認碼)    visitNum(訪問次數)

           使用者一申請找回密碼,我們就建立一條記錄,這個createTime可以是一個時間戳記,比如我們規定這個url的有效期間是24小時,就是通過擷取當前時 間戳與該欄位比 較即可,超過有效期間就提示使用者該url已到期。confirmCode和不建表一樣的構造,此時可以加上隨機欄位。visitNum可以事先放置我們允許的訪問次數,訪問一次就減1,如果為零便刪除該記錄,如果我們設定該url只能訪問一次有效,該欄位可以不要,只要一被訪問,我們就刪除該記錄即可。還有就是定時清理無效記錄,通過建立事件+儲存過程。

    至此關於這兩個爭論的描述結束,個人感覺用不用建表都能實現找回密碼功能,只是覺得建表要相對靈活,如果說佔用空間的話,我猜想一天之內能有千分之一乃至萬分之一的使用者在申請找回密碼就已經了不得了,所以記錄應該占不了多少空間,還有如果增加簡訊找回密碼功能,這個表還是有用的。

    好了,一開始我以為就這麼應該是完了的。但我在實際實現過程中發現比非如此。我們知道,訪問記憶體的速度最快,其次是檔案,最慢的是資料庫。據說駭客慣用的招數其中就有諸如寫個for迴圈,不停地訪問你的網站,讓你不停地操作資料庫,讓你的伺服器崩潰............. 據說網站的應對方法就是增加圖形驗證碼,因為圖形技術是很難的,不好突破,所以我們看到很多的網站都有驗證碼,什麼註冊、登入等等都是.........所以我在實際操作中給使用者郵箱發的是一個表單驗證,其中就包含驗證碼,可惜的是只要一提交,就被騰訊屏蔽(因為我用的是QQ郵箱進行測試),鬱悶死我了。但我是那種輕言放棄的人嗎,顯然不是,我又想可以通過像之前一樣,只發個url加驗證碼資訊,而這個url跳到的是一個表單驗證的地方(騰訊沒有屏蔽我的url,嚇死我了)。

    所以我的做法是這樣的。大致流程如下:



         感覺是不是很開心啊,如果你也覺得我是對的,那就大錯特錯了,哈哈哈哈哈.........這裡面有一個隱藏的錯誤,就是session的生存期問題,驗證碼存在session中,而session的生存期預設為1440秒,也就是24分鐘。所以這個得注意,只要稍微注意一下,但基本實現是可以的。這個頁面這麼看怎麼彆扭,你可以將擷取確認碼和提交確認分成兩個頁面就行了。

        突然想到,如果連驗證碼都沒用了,該咋辦。

        能不能訪問某個URL,或某個URL是否有效,最直接的辦法是什麼。那就是這個URL根本不存在,URL不存在也就是其對應的檔案不存在,這樣我們就可以通過瀏覽器幫我們給那些亂改我們的URL或者不斷請求企圖造成伺服器癱瘓的惡意破壞者提示個“404”錯誤。那如果瀏覽器都不行,那咋辦。嗯....那我們就不上網了。具體做法如下:

        1、使用者提交找回密碼申請

        2、網站驗證資訊是否正確,正確則構造一唯一隨機字串=無法復原加密(使用者ID+原密碼+time()等),構造url=隨機字串.php。id=使用者ID&email=使用者郵箱,同時產生與隨機字串同名的php檔案。將該url發至使用者郵箱。簡單的流程代碼如下:

       <?php
            ...省略...

            $fileName = '隨機字串.php';

            $content = "<?php header('Location:findPwd.php?id=$id&email=$email') ?>";

            file_put_contents($fileName,$content);//檔案不存在該函數會自動產生

             ...省略...
       ?>


      3、使用者登入郵箱,點選連結,如果連結存在,則不會出現404錯誤

      4、網站在

      findPwd.php

      <?php

            //用HTTP_REFERER擷取跳轉來源,判斷是不是從我們的網站跳轉過來的,合法則繼續執行,這應該是防盜鏈的內容,由於不知道怎樣做才完美,待研究。

.....

            $id = $GET['id'];

            $email = $GET['email'];

           //驗證資訊正確性,重設密碼,提醒使用者,同時刪除相應的隨機字串.php,這樣就只能訪問一次了,當然這個檔案的有效期間可以定期清理(建事件+預存程序),

           //可以通過filemtime(隨機字串.php)擷取最近被修改的時間和目前時間比較來決定,如“目前時間-filemtime(隨機字串.php)>24小時”則刪除

           .....

      ?>

    這次是真完了。文中用了很多“據說”....沒辦法,沒參加過真實的生產實踐,不知道實際公司是怎麼做的,有說的不對的,歡迎指正。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.