PHP会话管理——Session和Cookie
會話管理包括:Session和Cookie,主要功能都是把客戶端和服務器關聯起來,用于管理和查看用戶在網站中的狀態。
背景
Web應用程序是使用HTTP協議傳輸數據的。HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的連接就會關閉,再次交換數據需要建立新的連接。這就意味著服務器無法從連接上跟蹤會話。即用戶A購買了一件商品放入購物車內,當再次購買商品時服務器已經無法判斷該購買行為是屬于用戶A的會話還是用戶B的會話了。要跟蹤該會話,必須引入一種機制。
Cookie就是這樣的一種機制。它可以彌補HTTP協議無狀態的不足。在Session出現之前,基本上所有的網站都采用Cookie來跟蹤會話。
可以把Cookies看成為http協議的一個擴展
Cookie和Session對比
| 定位 | cookie 是由服務器發送到瀏覽器的變量 | Session用來追蹤每個用戶的會話 |
| 調用語句 | setcookie() ,必須在任何輸出前調用,位于 標簽之前 | session_start(),必須在任何輸出前調用,位于 標簽之前 |
| 存放位置 | 基于客戶端瀏覽器,存放在內存/硬盤 | 服務端內存 |
| 存儲大小 | 單個cookie小于3K | 無限制(過大會導致內存溢出) |
| 生命周期 | 瀏覽器會話期間/設定時間 | 超時時間(未訪問過服務器的最長時間) |
| 依賴性 | 依賴于瀏覽器 | 依賴于Cookie |
| 安全性 | 不安全 | 較安全 |
Cookie
Cookie意為“甜餅”,是由W3C組織提出,最早由Netscape社區發展的一種機制。目前Cookie已經成為標準,所有的主流瀏覽器如IE、Netscape、Firefox、Opera等都支持Cookie。
注意:Cookie功能需要瀏覽器的支持。如果瀏覽器不支持Cookie(如大部分手機中的瀏覽器)或者把Cookie禁用了,Cookie功能就會失效。不同的瀏覽器采用不同的方式保存Cookie。
Cookie的工作原理:由于HTTP是一種無狀態的協議,服務器單從網絡連接上無從知道客戶身份。怎么辦呢?就給客戶端們頒發一個通行證吧,每人一個,無論誰訪問都必須攜帶自己通行證。這樣服務器就能從通行證上確認客戶身份了。
Set-Cookie 和 Cookie:兩個專門負責設置以及發送cookie的http頭部。
Cookie工作流程:
Cookie實際上是一小段的文本信息。(1)整個客戶端請求服務器,(2)如果服務器需要記錄該用戶狀態,則通過服務器返回給客戶端一個包含Set-Cookie這個頭部的http響應來指示客戶端建立一個cookie。客戶端瀏覽器會把Cookie保存起來,直到這個cookie過期。(3)當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。(4)服務器檢查該Cookie,以此來辨認用戶狀態,然后響應請求。注意:服務器還可以根據需要修改Cookie的內容。一個cookie的設置以及發送過程分為以下四步:
setcookie() 定義一個和其余的 HTTP 標頭一起發送的 cookie。和其它標頭一樣,cookie 必須在腳本的任何其它輸出之前發送(這是協議限制)。這需要將本函數的調用放到任何輸出之前,包括 <html> 和 <head> 標簽以及任何空格。如果在調用 setcookie() 之前有任何輸出,本函數將失敗并返回 FALSE。因此必須在發送任何HTML(必須位于 標簽之前)、文本信息前調用session_start() 函數。
- Cookie的限制:
- 瀏覽器記錄Cookie的容量不能大于4KB;
- 每個瀏覽器只能保存某個服務器上的20個Cookie。如果保存更多,則最先保存的就會被刪除;
- 每個用戶的瀏覽器最多只能訪問300個Cookie。
- 創建Cookie:setcookie(變量名,變量值,過期時間,在服務器上的有效路徑,boolean是否通過安全的HTTPS鏈接傳送);
- Cookie不會在設置本頁生效,在測試時,要在Cookie過期之前,通過另外一個頁面來訪問。
- 工作時間:
- 不設置過期時間:重新打開瀏覽器則失效;表示這個cookie生命周期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽會話期的cookie被稱為會話cookie。
- time()+ n秒數:設定過n秒后Cookie失效;
- mktime(時,分,秒,月,日,年),設定為到規定時間失效;
會話cookie一般不保存在硬盤上而是保存在內存里。如果設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie依然有效直到超過設定的過期時間。
Cookie的有效期:Cookie的maxAge決定著Cookie的有效期,單位為秒(Second)。Cookie中通過getMaxAge()方法與setMaxAge(int maxAge)方法來讀寫maxAge屬性。
- maxAge屬性為正數,則表示該Cookie會在maxAge秒之后自動失效。瀏覽器會將maxAge為正數的Cookie持久化,即寫到對應的Cookie文件中。無論客戶關閉了瀏覽器還是電腦,只要還在maxAge秒之前,登錄網站時該Cookie仍然有效。
- maxAge為負數的Cookie,為臨時性Cookie,稱為會話Cookie,不會被持久化,不會被寫到Cookie文件中。
maxAge為0,則表示刪除該Cookie。Cookie機制沒有提供刪除Cookie的方法,因此通過設置該Cookie即時失效實現刪除Cookie的效果。失效的Cookie會被瀏覽器從Cookie文件或者內存中刪除。
1
2
3
4
5
6
7
8//設置cookie過期時間
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(Integer.MAX_VALUE); // 設置生命周期為MAX_VALUE
response.addCookie(cookie); // 輸出到客戶端
//刪除cookie
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(0); // 設置生命周期為0,不能為負數
response.addCookie(cookie); // 必須執行這一句注意:從客戶端讀取Cookie時,包括maxAge在內的其他屬性都是不可讀的,也不會被提交。瀏覽器提交Cookie時只會提交name與value屬性。maxAge屬性只被瀏覽器用來判斷Cookie是否過期。
Cookie數組:將cookie各個變量聯系起來,組成數組,利用$_COOKIE[’cookie‘]輸出。Cookie對象使用key-value屬性對的形式保存用戶狀態,一個Cookie對象保存一個屬性對,一個request或者response同時使用多個Cookie。
提高Cookie安全性的方法有:
設置HttpOnly為true。該屬性值的作用就是防止Cookie值被頁面腳本讀取。
但是設置HttpOnly屬性,HttpOnly屬性只是增加了攻擊者的難度,Cookie盜竊的威脅并沒有徹底消除,因為cookie還是有可能傳遞的過程中被監聽捕獲后信息泄漏。
設置Secure為true。給Cookie設置該屬性時,只有在https協議下訪問的時候,瀏覽器才會發送該Cookie。
把cookie設置為secure,只保證cookie與WEB服務器之間的數據傳輸過程加密,而保存在本地的cookie文件并不加密。如果想讓本地cookie也加密,得自己加密數據。
給Cookie設置有效期。
特性:
- Cookie不提供修改、刪除操作。如果要修改某個Cookie,只需要新建一個同名的Cookie,添加到response中覆蓋原來的Cookie。如果要刪除某個Cookie,只需要新建一個同名的Cookie,并將maxAge設置為0,并添加到response中覆蓋原來的Cookie。
注意:修改、刪除Cookie時,新建的Cookie除value、maxAge之外的所有屬性,例如name、path、domain等,都要與原Cookie完全一樣。否則,瀏覽器將視為兩個不同的Cookie不予覆蓋,導致修改、刪除失敗。
- Cookie具有不可跨域名性。根據Cookie規范,瀏覽器依據域名判斷一個網站是否能操作另一個網站Cookie的(域名相同才可以操作)。同一個一級域名下的兩個二級域名也不能交互使用,只有嚴格相同的域名可以交互使用。
如:瀏覽器訪問Google只會攜帶Google的Cookie,而不會攜帶Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。Cookie在客戶端是由瀏覽器來管理的。瀏覽器能夠保證Google只會操作Google的Cookie而不會操作Baidu的Cookie,從而保證用戶的隱私安全。
- Unicode編碼:保存中文。中文與英文字符不同,中文屬于Unicode字符,在內存中占4個字符,而英文屬于ASCII字符,內存中只占2個字節。Cookie中使用Unicode字符時需要對Unicode字符進行編碼,否則會亂碼。
提示:Cookie中保存中文只能編碼。一般使用UTF-8編碼即可。不推薦使用GBK等中文編碼,因為瀏覽器不一定支持,而且JavaScript也不支持GBK編碼。
- BASE64編碼:保存二進制圖片.Cookie不僅可以使用ASCII字符與Unicode字符,還可以使用二進制數據。例如在Cookie中使用數字證書,提供安全度。使用二進制數據時也需要進行編碼。
注意:本程序僅用于展示Cookie中可以存儲二進制內容,并不實用。由于瀏覽器每次請求服務器都會攜帶Cookie,因此Cookie內容不宜過多,否則影響速度。Cookie的內容應該少而精。
除了cookie,客戶端傳遞數據到服務器端的方式還包括POST(數據包含在http請求的內容區域內)和GET(數據包含在請求的url中)。這兩種傳遞數據的方式,比起用cookies來傳遞數據更穩定,因為cookie可能被禁用,但是以GET以及POST方式傳遞數據時,不存在這種情況。
Session
Session是服務器端使用的一種記錄客戶端狀態的機制,使用上比Cookie簡單一些,相應的也增加了服務器的存儲壓力。
Session技術則是服務端的解決方案,它是通過服務器來保持狀態的。由于Session這個詞匯包含的語義很多,因此需要在這里明確一下。
Session的含義
- 把客戶端瀏覽器與服務器之間一系列交互的動作稱為一個Session。涉及到Session持續的時間和操作等等;
- Session指的是服務器端為客戶端所開辟的存儲空間,在其中保存的信息就是用于保持狀態。涉及Session中存放的內容及匹配的內容方法等。
Session使用流程:
- 創建Session。在服務器端程序運行的過程中創建Session,同時,服務器為該Session生成唯一的Session id,這個Session id在隨后的請求中會被用來匹配已經創建的Session;
- 在Session被創建之后,就可以調用Session相關的方法往Session中增加內容了,而這些內容只會保存在服務器中,發到客戶端的只有Session id;
- 當客戶端再次發送請求的時候,會將這個Session id帶上,服務器接受到請求之后就會依據Session id找到相應的Session,從而再次使用之。
正是這樣一個過程,用戶的狀態也就得以保持了。
Session里的信息應該盡量精簡。因為Session保存在服務器端。為了獲得更高的存取速度,服務器一般把Session放在內存里。每個用戶都會有一個獨立的Session。如果Session內容過于復雜,當大量客戶訪問服務器時可能會導致內存溢出。
Session在用戶第一次訪問服務器的時候自動創建。需要注意只有訪問JSP、Servlet等程序時(向服務器發送請求時)才會創建Session,只訪問HTML、IMAGE等靜態資源并不會創建Session。Session生成后,只要用戶繼續訪問,服務器就會更新Session的最后訪問時間,并維護該Session。用戶每訪問服務器一次,無論是否讀寫Session,服務器都認為該用戶的Session“活躍(active)”了一次。
Session的有效期
由于會有越來越多的用戶訪問服務器,因此Session也會越來越多。為防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過服務器,Session就自動失效了。
Session的超時時間為maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也可以在web.xml中修改。另外,通過調用Session的invalidate()方法可以使Session失效。
Session對瀏覽器的要求
Session保存在服務器,對客戶端是透明的。由于Session需要使用Cookie作為識別標志,它的正常運行仍然需要客戶端瀏覽器的支持。Session依據Cookie來識別是否為同一用戶。該Cookie為服務器自動生成的,它的maxAge屬性一般為–1,表示僅當前瀏覽器內有效,并且各瀏覽器窗口間不共享,關閉瀏覽器就會失效。
注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外。子窗口會共用父窗口的Session。例如,在鏈接上右擊,在彈出的快捷菜單中選擇“在新窗口中打開”時,子窗口便可以訪問父窗口的Session。
URL地址重寫
如果客戶端瀏覽器將Cookie功能禁用,或者不支持Cookie怎么辦?例如,絕大多數的手機瀏覽器都不支持Cookie。Java Web提供了另一種解決方案:URL地址重寫。
URL地址重寫是對客戶端不支持Cookie的解決方案。URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中。服務器能夠解析重寫后的URL獲取Session的id。這樣即使客戶端不支持Cookie,也可以使用Session來記錄用戶狀態。HttpServletResponse類提供了encodeURL(Stringurl)實現URL地址重寫。
Cookie與Session的區別
如果說Cookie機制是通過檢查客戶身上的“通行證”來確定客戶身份的話,那么Session機制就是通過檢查服務器上的“客戶明細表”來確認客戶身份。Session相當于程序在服務器上建立的一份客戶檔案,客戶來訪的時候只需要查詢客戶檔案表就可以了。
cookie數據存放在客戶的瀏覽器上,session數據放在服務器上;
- cookie不是很安全,別人可以分析存放在本地的COOKIE并進行COOKIE欺騙,考慮到安全應當使用session;
- session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能。考慮到減輕服務器性能方面,應當使用COOKIE;
- 單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能超過3K;
小結
Cookie和Session的方案雖然分別屬于客戶端和服務端,但是服務端的session的實現對客戶端的cookie有依賴關系的,上面我講到服務端執行session機制時候會生成session的id值,這個id值會發送給客戶端,客戶端每次請求都會把這個id值放到http請求的頭部發送給服務端,而這個id值在客戶端會保存下來,保存的容器就是cookie,因此當我們完全禁掉瀏覽器的cookie的時候,服務端的session也會不能正常使用(注意:有些資料說ASP解決這個問題,當瀏覽器的cookie被禁掉,服務端的session任然可以正常使用,ASP我沒試驗過,但是對于網絡上很多用php和jsp編寫的網站,我發現禁掉cookie,網站的session都無法正常的訪問)。
參考:
總結
以上是生活随笔為你收集整理的PHP会话管理——Session和Cookie的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 纪念碑谷第九关过关流程图文攻略
- 下一篇: 动态规划算法php,php算法学习之动态