背景
cookie與session都是為了保持訪問客戶與后端服務(wù)器的交互狀態(tài),有各自的優(yōu)點(diǎn)也有各自的缺點(diǎn)。
cookie與session的關(guān)系非常緊密胜卤,對于不了解概念的同學(xué)經(jīng)常會弄混淆瑟曲,下面我從各個方面來介紹(用自己的理解)cookie和session。
Cookie
1.概念
cookie:客戶端向服務(wù)端發(fā)起請求呻征,服務(wù)端會傳遞一些key/value值給客戶端,這樣下次客戶端訪問服務(wù)器時(shí)罢浇,服務(wù)器能識別到客戶的身份等信息陆赋,這對于互聯(lián)網(wǎng)的體驗(yàn),后端的區(qū)別處理都有重大的意義嚷闭。這些key/value值會保存在客戶端攒岛,稱為"cookie"。
使用上來講胞锰,它只是HTTP協(xié)議頭中的一個字段灾锯。
2.屬性值
當(dāng)前cookie有兩個版本:Version0和Version1
主要屬性:
Expires:過期時(shí)間,在設(shè)置的某個時(shí)間點(diǎn)后該Cookie會失效
Domain:生成該Cookie的域名
Path:該Cookie是在當(dāng)前哪個路徑下生成的
Secure:如果設(shè)置該屬性嗅榕,那么只會在SSH連接時(shí)才會回傳該Cookie
3.使用cookie的限制
Cookie是HTTP協(xié)議頭中的一個字段顺饮,最終被存儲在瀏覽器里,所以不同的瀏覽器對Cookie的存儲都會有些限制凌那,例如chrome兼雄,50個/每個域名,cookie總大小 大于8w個字節(jié)帽蝶;firefox? 50個/每個域名赦肋,4097個字節(jié)
Session
1. 概念
代表客戶端與服務(wù)器的一次會話過程〕凹睿客戶端第一次訪問服務(wù)器時(shí)會生成一個sessionID(服務(wù)器端生成的)金砍,每個客戶端是唯一的,這樣每次客戶端和服務(wù)器交互麦锯,不需要每次都回傳所有的Cookie值恕稠,只需要傳回一個ID即可,這個ID通常是NAME為JSESIONID的一個Cookie扶欣。也即鹅巍,session是基于Cookie實(shí)現(xiàn)的千扶,是一個特殊的Cookie。
在Servlet中骆捧,session指的是HttpSession類的對象澎羞。
2. 存儲
session存放在服務(wù)器端的內(nèi)存中,不過session可以通過特殊的方式做持久化管理敛苇。
3. 生命周期
創(chuàng)建和使用:客戶端第一次請求session對象時(shí)妆绞,如果沒有,服務(wù)器會為客戶端創(chuàng)建一個session枫攀,并生成一個sessionID括饶,用來標(biāo)識該session對象,當(dāng)瀏覽器下次請求別的資源時(shí)来涨,瀏覽器會將此sessionID放置在請求頭中图焰,服務(wù)器接收到請求后就得到該請求的sessionID,找到該ID的session返還給請求者使用蹦掐。一個會話只有一個session對象技羔,根據(jù)sessionID唯一確認(rèn)。
刪除:
1. session超時(shí)后刪除
2. 調(diào)用HttpSession.invalidate()
3. 服務(wù)器關(guān)閉或服務(wù)停止
ps. session超時(shí):超時(shí)是指連續(xù)一定時(shí)間服務(wù)器沒有收到該Session所對應(yīng)客戶端的請求卧抗,并且這個時(shí)間超過了服務(wù)器設(shè)置的Session超時(shí)的最大時(shí)間藤滥。
cookie與session的對比
1. 安全性
cookie可以在瀏覽器中使用工具被查看、編輯社裆、添加超陆、修改,安全性令人堪憂浦马;而session對象被保存在服務(wù)器端,通過cookie傳遞一個SessionID而已张漂,更適合存用戶隱私和重要的數(shù)據(jù)晶默。
2. 一致性
Cookie能解決同一個用戶的請求不在同一臺服務(wù)器處理而導(dǎo)致的cookie不一致問題,簡單而粗暴航攒;而Session存儲在服務(wù)器端磺陡,當(dāng)一個應(yīng)用由一個集群提供服務(wù)時(shí),需要解決session同步的問題漠畜。
3. 存儲
cookie存儲在瀏覽器中币他,有大小限制,且當(dāng)同一域名下有多個應(yīng)用系統(tǒng)憔狞,cookie的使用和管理容易混亂蝴悉、超出限制;而session的統(tǒng)一管理可以解決這些問題瘾敢。
總而言之拍冠,session是為了彌補(bǔ)cookie的一些限制和缺點(diǎn)尿这,作為解決方案而出現(xiàn)的。下面介紹session的分布式架構(gòu)庆杜。
相關(guān)幾個擴(kuò)展
1. 分布式session架構(gòu)
如下圖射众,左上方有一個服務(wù)訂閱服務(wù)器,在應(yīng)用系統(tǒng)啟動時(shí)晃财,可以從這個訂閱服務(wù)器訂閱這個應(yīng)用需要的叨橱、可寫的session項(xiàng)和可寫的cookie項(xiàng),這些配置的session和cookie可以限制這個應(yīng)用能夠使用那些session和cookie断盛,甚至可以控制session和cookie的可讀或者可寫罗洗,以有效控制session的安全性和cookie的數(shù)量。
通過統(tǒng)一的訂閱服務(wù)器的推送配置郑临,可以有效地集中管理資源栖博,簡化cookie的管理。
由于應(yīng)用是一個集群厢洞,所以不可能將創(chuàng)建的Session都保存在每臺應(yīng)用服務(wù)器的內(nèi)存中仇让。所以若要共享,必須將它們存儲在一個分布式緩存中躺翻,可隨時(shí)讀丧叽、寫,MemCache或者淘寶開源的分布式緩存系統(tǒng)tair都可以選擇公你。
如何實(shí)現(xiàn)session和cookie的讀寫踊淳?
1. 重新實(shí)現(xiàn)HttpSession操作接口,通過InnerHttpSession對象來操作session
2. 配置一個filter攔截用戶請求陕靠,在請求進(jìn)入應(yīng)用前完成session和cookie的讀寫
2. 跨域名同步session
要實(shí)現(xiàn)跨域名session同步迂尝,需要另一個跳轉(zhuǎn)應(yīng)用(成為jump應(yīng)用),這個應(yīng)用可以被多個域名訪問剪芥,主要功能是從一個域名下取得sessionID垄开,然后將這個sessionID同步到另外一個域名下。
3. 解決cookie被盜
問題:登錄成功后税肪,cookie被盜溉躲,盜取人將你的cookie加入到他的瀏覽器,就可以通過你的cookie正常訪問你的個人信息了
解決:在分布式session中益兄,設(shè)置一個session簽名锻梳,當(dāng)用戶登錄成功后,根據(jù)用戶的私密信息生成一個簽名净捅,以表示當(dāng)前這個唯一合法的登錄狀態(tài)疑枯,將這個簽名作為一個cookie在當(dāng)前這個用戶的瀏覽器進(jìn)程中和服務(wù)器傳遞,用戶每次訪問服務(wù)器都檢查這個簽名和服務(wù)器從分布式緩存中取出的session重新生成的簽名是否一致蛔六,如果不一致神汹,則判斷這個用戶的登錄狀態(tài)不合法庆捺,服務(wù)器端將清除這個sessionID在分布式緩存中的session信息,讓用戶重新登錄屁魏。 ?是否有性能問題滔以?
4. 表單重復(fù)提交問題
網(wǎng)站中很多地方都有表單提交的問題,如網(wǎng)速慢氓拼、用戶惡意發(fā)送重復(fù)請求你画,在這些場景下,需要設(shè)計(jì)一個攔截表單重復(fù)提交的機(jī)制桃漾。
防止表單提交坏匪,需要有一個字段標(biāo)識用戶的每一次提交,使得每一次提交都是唯一的撬统。那么适滓,可以在表單域里增加一個隱藏的表單項(xiàng),這個表單項(xiàng)的值每次都是唯一的token恋追。
當(dāng)用戶請求該頁面時(shí)凭迹,生成唯一的token,并保存在用戶的session中苦囱;等用戶提交時(shí)嗅绸,檢查這個token和當(dāng)前session中保存的token是否一致,如果一致撕彤,說明沒有重復(fù)提交鱼鸠,否則,用戶提交上來的token已經(jīng)不是當(dāng)前的這個請求的合法token羹铅。
小結(jié)
本文對cookie和session做了簡要的介紹蚀狰,它們都是為了保證客戶端和服務(wù)端訪問的連續(xù)性。為什么包保證連續(xù)性职员?一方面造锅,用戶體驗(yàn)上更良好,也方便后端的業(yè)務(wù)實(shí)現(xiàn)廉邑,另一方面,也可以簡單后端實(shí)現(xiàn)倒谷,提高訪問性能蛛蒙。cookie使用簡單、但數(shù)量大小有限制渤愁,也存在安全問題牵祟,而session,基于cookie抖格,作為補(bǔ)充诺苹,解決了安全咕晋、同步、跨域等問題收奔,兩者相輔相成掌呜,共同完成使命。