考慮一個(gè)問題: 如何抓取一個(gè)訪問受限的網(wǎng)頁?如校內(nèi)好友的主頁,個(gè)人新鮮事頁面等。 顯然,通過瀏覽器,我們可以手動(dòng)輸入用戶名密碼來訪問目標(biāo)頁面,所謂“抓取”,只不過需要使用程序來模擬完成同樣的工作,因此需要了解“登陸”過程中到底發(fā)生了什么。 對(duì)未登錄用戶,服務(wù)器強(qiáng)制用戶跳轉(zhuǎn)到登陸頁面,用戶鍵入用戶名密碼并提交,服務(wù)器將用戶POST的信息與數(shù)據(jù)庫中信息比對(duì),如通過則跳轉(zhuǎn)至landing page。那么在我們?cè)L問其他頁面的時(shí)候,服務(wù)端如何判斷我們的身份呢?由于HTTP協(xié)議是無狀態(tài)的,顯然,服務(wù)器不可能直接知道我們?cè)谏弦幻雱倓偟卿洺晒Α?/P> 最簡單的思路,就是用戶每個(gè)POST請(qǐng)求中,都需要帶上用戶名與密碼來標(biāo)識(shí)自己的身份;這樣雖然可行,但大大加重了服務(wù)器的負(fù)擔(dān)(對(duì)于每個(gè)request都需要到數(shù)據(jù)庫驗(yàn)證),也大大降低了用戶體驗(yàn)(每個(gè)頁面都需要重新輸入用戶名密碼,每個(gè)頁面都帶有登錄表單)。 因此,誕生了一個(gè)解決方案:cookie。cookie,簡而言之就是在本地計(jì)算機(jī)保存一些用戶操作的歷史信息(當(dāng)然包括登錄信息),并在用戶再次訪問該站點(diǎn)時(shí)瀏覽器通過HTTP協(xié)議將本地cookie內(nèi)容發(fā)送給服務(wù)器,從而完成驗(yàn)證,或繼續(xù)上一步操作。 進(jìn)一步的,誕生了另外一種解決方案:session,簡而言之就是在服務(wù)器上保存用戶操作的歷史信息。但該方式下,仍然需要將發(fā)送請(qǐng)求的客戶端與session對(duì)象進(jìn)行對(duì)應(yīng),所以可以借助cookie機(jī)制來獲取客戶端的標(biāo)識(shí)(即session id),也可以通過GET方式將id提交給服務(wù)器。session id,即服務(wù)器上session對(duì)象文件的名稱,由服務(wù)器負(fù)責(zé)產(chǎn)生,保證隨機(jī)性與唯一性,相當(dāng)于一個(gè)隨機(jī)密鑰,避免在握手或傳輸中暴露用戶真實(shí)密碼,類似的設(shè)計(jì)思想在SSO與OpenID中也經(jīng)常用到。 再插入一個(gè)問題:為什么對(duì)于一些網(wǎng)站,關(guān)閉瀏覽器之后,session就失效了? 從上文可以知道,session一般通過cookie來保存session id,如果cookie設(shè)置為關(guān)閉瀏覽器就刪除(expire),那么無論如何設(shè)置session的超時(shí)機(jī)制,由于瀏覽器重新啟動(dòng)時(shí)再也找不到原來的cookie了,因此服務(wù)器只能重新為其分配session id。 問題3:cookie和session的區(qū)別? 如上文所述,session和cookie的目的相同,都是為了克服http協(xié)議無狀態(tài)的缺陷,但完成的方法不同。session通過cookie,在客戶端保存session id,而將用戶的其他會(huì)話消息保存在服務(wù)端的session對(duì)象中,與此相對(duì)的,cookie需要將所有信息都保存在客戶端。因此cookie存在著一定的安全隱患,例如本地cookie中保存的用戶名密碼被破譯,或cookie被其他網(wǎng)站收集(例如:1. appA主動(dòng)設(shè)置域B cookie,讓域B cookie獲??;2. XSS,在appA上通過javascript獲取document.cookie,并傳遞給自己的appB)。 在當(dāng)初寫php App時(shí),知道通過SSO可以從Session中獲取userid,但不知其所以然,于是遇到一個(gè)奇怪的問題:瀏覽器A標(biāo)簽?zāi)_本執(zhí)行過程中,打開B標(biāo)簽訪問同一個(gè)腳本,會(huì)被pending,直到A執(zhí)行完畢。原因該腳本執(zhí)行了session_start(),而php session_start()后對(duì)該session的寫入是排他的,只有當(dāng)腳本執(zhí)行結(jié)束或顯式執(zhí)行session_destroy()才能釋放session文件鎖。因?yàn)椴恢纒ession的工作原理,被困擾了整整一個(gè)工作日!類似的問題還有因?yàn)椴涣私釲amp中字符編碼的轉(zhuǎn)換規(guī)則,導(dǎo)致某些在gbk和gb2312差集中的文字無法入庫。 所以,知其然,還需要知其所以然。磨刀不誤砍柴工,授人以漁,做web開發(fā)之前,有必要將一些必要知識(shí)了解清楚,才不會(huì)在用到時(shí)候捉襟見肘,或是在調(diào)bug時(shí)候如無頭蒼蠅亂轉(zhuǎn)。做好自身建設(shè),永遠(yuǎn)比case by case地被動(dòng)滿足來得高明。 |
|