原始文章(我的部落格):
http://blog.tuzaiz.id...hives/26大家都知道,許多服務網站都一定會有一個用戶系統,供用戶註冊、登入、登出,這也成為私人保護的第一道門戶!
那一個會員系統又該要如何去作設計呢?其實用戶系統是一個很簡單的概念,如上面所寫,主要就是註冊、登入、登出三種功能,而這三個功能細分的話就會如下面:
註冊
1. 輸入表單 → 2. 資料檢查(帳號重疊、輸入內容與安全性) → 3. 存入資料庫
登入
1. 登入表單 → 2. 檢查帳號密碼 → 3. 比對正確則登記登入
登出
1. 註銷登入資料與所有變數!
其實這幾項的概念都相當簡潔,但是這也是整個網站的第一步,因此雖然簡單卻要最嚴謹去設計,包括安全與漏洞都要小心謹慎!
在做任何網站之前,最重要的事情就是先做好規劃,切忌邊做邊想邊修改,這樣不但會讓自己的邏輯混亂,也會讓自己的程式弄的相當亂,難以修改!
設計資料庫
在寫程式之前,先將我們規劃好需要用到的資料設計成資料庫,這邊我使用MySQL,一個簡單的用戶系統大概只要一個到兩個的資料表就好,養成習慣盡量不要讓資料庫弄的太過複雜,多多利用MySQL的關聯資料庫功能!
這邊假設我想要製作兩個資料表,一個存放帳號資料(user)另一個存放個人資料(personal)
帳號資料
資料表名稱: user
* 資料表欄位: user_id (這設為主鍵,使用數字格式(INT),並且依照使用習慣使用自動遞增,作為每個帳號獨立的ID)
* user_name (使用者名稱,使用字串格式(VARCHAR),長度依自己選擇大約在20左右即可)
* user_pass (使用者密碼,也使用字串格式(VARCHAR),為了安全我使用MD5編碼所以長度設大一點,約100即可
個人資料
資料表名稱:personal
* 資料表欄位: user_id (作為與帳號資料的關聯,由於一個帳號只會有一個個人資料,因此可以以此為主鍵或是另外增加一個person_id作主鍵而user_id作索引鍵都可以)
* person_name (個人姓名,依自己設計的資料內容作設計,使用字串VARCHAR,長度20)
* person_birth (個人生日,可選擇用字串儲存或是DATE儲存,內容格式不同,下面會作解釋)
* 其他資料可依照網站需求來作設計
註冊會員
第一步:顯示表單
這應該不用太做說明,就依照自己資料庫的設計來作HTML表單而已!以我的設計來說就是一個帳號、兩個密碼(避免輸入錯誤用)
第二步:驗證輸入資料
這一步很重要,不但要注意是不是有輸入資料,還要注意資料內容格式對不對,最重要的就是要注意是不是有人可以利用輸入資料來破壞你的資料庫(這是一個很明顯的問題,下面我會稍微解釋一下)!
網頁設計師有一句流傳下來的話,就是永遠不要相信使用者輸入的資料,千萬不要用自己的邏輯去判斷別人不會這樣作,一定要避免掉所有可能會造成破壞的問題!
所謂利用表單來破壞資料庫,就是人家在字串輸入的表單中輸入的內容會導致資料庫的修改或破壞,下面作個假設
我設計一個表單送出後會將輸入資料送出到MySQL中存放,PHP操縱MySQL的方式都是依靠SQL指令來進行,假設我有一個表單是送出後要插入到資料庫中,那我會用下面那個SQL來操作
1. INSERT INTO `database` (`name`) VALUES ('{$value}');
database是資料表名稱
`name` 是欄位名稱
$value 是輸入表單內容存放的變數
假設我輸入的資料是1 那這個SQL就會是
1. INSERT INTO `database` (`name`) VALUES (Ƈ');
這樣程式就會很正常的輸入1這個數值到資料庫中存放,可是這是理論上,如果使用者不輸入一般文字,而輸入像下面這樣
1. '); DELETE FROM `database`; INSERT INTO `databse` (`name`) VALUES ('
這樣子如果我們不避免掉的話,就會變成
1. INSERT INTO `database` (`name`) VALUES (''); DELETE FROM `database`; INSERT INTO `databse` (`name`) VALUES ('');
也就是可以將資料庫中所有資料全部刪除掉!記住,不要相信自己的理論,不要認為使用者不會知道你的資料庫名稱,或是使用者不會這樣作,有這點風險我們都要避免!
還有另一種危險就是要小心使用者輸入HTML碼來破壞整個網站的版面!
這只要使用htmlspecialchars() 這個函式就可以跳脫HTML碼
1. $value = htmlspecialchars($value);
使用者帳號:
帳號方面要注意,首先是你的帳號是否願意支援中文,長度要在多少(要避免超過資料庫設計時的上限),注意SQL安全問題
一般來說是建議不要使用中文來當作使用者帳號,因為中文在程式中與英文結構不同,在BIG5的格式中PHP會對幾個字(許功蓋)造成錯誤問題,而現在雖然MySQL已經支援了多語系且可以使用Unicode,但是還是建議盡量使用英文字母、底線與數字來作為帳號!
長度我們也要注意,一般最好是4個字以上15個字以下,如果支援中文要記得中文一個字代表兩個字元!這邊檢查最好使用正規表達式來作檢測!
1. ereg("^[a-zA-Z0-9_]{4,15}$", $user_name);
這樣就只能接受由數字、英文與底線所組成的4~15個字元的內容!
接下來就是最最重要的,就是注意使用者帳號千萬不能跟其他人的重疊,所以要先檢查是不是有這個使用者名稱存在喔!
使用者密碼:
密碼除了上面的SQL安全與長度之外,還要注意密碼能夠輸入的字元,現在為了密碼的安全,一般我們會建議使用者在密碼的設計上盡量要更加的安全,所謂的安全密碼大概有下面幾條規則
* 不可由數字開頭
* 需包含數字、英文字母大寫、英文字母小寫、符號其中三種來作組合
* 符號使用半形可直接輸入的符號,並且避免用引號(’ “)
因為這樣,所以除了要避免SQL安全之外,我們還要針對一些可能會造成程式判斷錯誤的符號進行跳脫(如; ‘ ” \ NULL ),這問題很好解決,只要在密碼的變數使用addslashes這個函式就可以了
1. $user_pass = addslashes($user_pass);
一樣,密碼我們用正規表達式來判斷輸入是否正確
我習慣加上了一行 $user_pass = md5($user_pass); ,這是將密碼使用md5加密過後再放進資料庫中的作法,這樣一來人家經由資料庫或傳輸封包獲取你的密碼的可能性就大大降低,缺點是你的密碼遺失的話站長也無法幫你取得你的密碼,不過可以請站長重新幫你設定新的密碼,這種作法在各大網站中常常可以見到!
驗證過程如果有錯誤,那就顯示錯誤然後將網頁跳回前頁,資料驗證沒有錯誤的話,接著就只要將這些輸入的資料送進資料庫中存放就好!
使用者登入
登入系統也很簡單,主要就是使用SQL去查詢資料庫中是不是有這筆帳號密碼相同的資料,如果有就將登入資訊以SESSION或Cookie的方式暫存在電腦中,注意不要將重要資料如密碼放置於Cookie或SESSION中,因為這些會在電腦中留下紀錄,如果在公用電腦中上網難保人家會不會偷取的你的資料,我的習慣是只存放一個用戶ID和確認碼,其他資料則經過這個ID去資料庫中取得就好!
登入驗證
登入表單送出後,當然也要經過驗證動作,SQL安全當然是不用說得,而搜索的SQL就用SELECT
1. SELECT * FROM `user` WHERE `user_name`='{$user_name}' AND `user_pass`='{$user_pass}'
取出有相同帳號與密碼的資料,有資料就代表正確,沒有資料就是帳號密碼不存在或錯誤!
登入動作
我的習慣是將登入資料以Session方式保存,只保存在一個瀏覽器進程,關掉瀏覽器後過一段時間就需要重新登入才可以使用,雖然麻煩可是可以避免使用公共電腦的危險!
登入成功後我就將用戶ID放入Session中,並且設計演算一個確認碼同時放入Session中,以免人家假造Session,這確認碼的演算方式不能夠讓其他人知道,也可以利用md5加密編碼!
以後網頁只要讀取看看Session存不存在,確認碼與用戶ID是否配合,就可以判斷是否已經登入過!
登出
登出更簡單,只要將Session的變數都移除掉,並拿掉一切個人資料的存放,雖然簡單但是卻要小心謹慎,避免任何資料殘留的可能!
一個簡單的會員系統就是這樣寫出來的,概念很簡單卻要小心謹慎,對於初學者來說,這無非是最好的練習作品,這也是學習資料庫的第一步!