需求:
現(xiàn)A,、B兩個(gè)項(xiàng)目,運(yùn)行于同一tomcat下,,要求在A項(xiàng)目下登錄后,,B項(xiàng)目中同樣獲取登錄權(quán)限,支持同一用戶重復(fù)登錄,。
分析:
即要實(shí)現(xiàn)A,、B項(xiàng)目的session共享。
如何共享,?
A項(xiàng)目session創(chuàng)建后,、B項(xiàng)目則不創(chuàng)建新的session;
B項(xiàng)目能實(shí)時(shí)獲取A項(xiàng)目的session,;
需要有一塊共用空間保存A項(xiàng)目的session,。
思路:
A項(xiàng)目中進(jìn)行session管理,即所有的登錄操作均在A中進(jìn)行,;
使用cookie傳遞session信息給客戶端,,避免創(chuàng)建多個(gè)session;
維護(hù)共用空間中的session的生命周期,。
技術(shù)支持:
每一個(gè)web應(yīng)用程序都有唯一一個(gè)ServletContext實(shí)例對(duì)象,,被該web應(yīng)用下面的每一個(gè)servlet共享。tomcat支持不同項(xiàng)目的ServletContext實(shí)例共享,,如此就可以讓ServletContext對(duì)象充當(dāng)儲(chǔ)存session的公共空間,,而不需要序列化或數(shù)據(jù)庫存儲(chǔ),從而節(jié)約資源,;
服務(wù)器一般采用session機(jī)制實(shí)現(xiàn)登錄,,當(dāng)通過getSession()獲取session后服務(wù)端會(huì)將此session的id作為JSESSIONID值保存在cookie中返回給客戶端,客戶端通過JSESSIONID來與服務(wù)器的session匹配來找到唯一的用戶,。sessioon保存于服務(wù)端,,cookie保存于客戶端。當(dāng)用戶于A項(xiàng)目登錄后我們需要?jiǎng)?chuàng)建一個(gè)全局的cookie記錄A項(xiàng)目的session id,,以便在訪問B項(xiàng)目時(shí)獲取全局cookie的session id來找到A項(xiàng)目中對(duì)應(yīng)的session,,從而完成session共享。
實(shí)現(xiàn):
1.不同項(xiàng)目ServletContext共享
修改tomcat的service.xml文件
此處為了簡(jiǎn)便
其中項(xiàng)目mate配置了crossContext=”true”屬性,,即代表可在此項(xiàng)目中可調(diào)用另一個(gè)WEB應(yīng)用的ServletContext對(duì)象
2.管理A項(xiàng)目session的生命周期
web.xml配置session監(jiān)聽器
復(fù)制一份session存進(jìn)內(nèi)存中,,手動(dòng)來管理session的生命周期
3.A項(xiàng)目中進(jìn)行登錄,,并保存信息進(jìn)session
在項(xiàng)目A中獲取session,并存入一些測(cè)試屬性,,當(dāng)并將此session id以鍵值對(duì)形式存入cookie中,,創(chuàng)建一個(gè)作用域全局的cookie(1.此處使用其他key均可,使用JSESSIONID是為了訪問B項(xiàng)目后在訪問A項(xiàng)目getSession時(shí)不需要重新創(chuàng)建session,,節(jié)省資源,,2.設(shè)置全局是為了跨項(xiàng)目也能訪問到)
4.重寫項(xiàng)目B中獲取session的方法,使其不自動(dòng)創(chuàng)建,,而是使用A項(xiàng)目的session
獲取A項(xiàng)目中的session集合,,通過全局的cookie中的session id即可找到A中對(duì)應(yīng)的session
5.項(xiàng)目B中獲取session,操作其中屬性
6.查看結(jié)果
A調(diào)用完成后客戶端會(huì)存在2個(gè)cookie,,一個(gè)自動(dòng)創(chuàng)建,,一個(gè)人創(chuàng)建
訪問B項(xiàng)目時(shí)即可攜帶全局的cookie
查看打印結(jié)果:
調(diào)用A項(xiàng)目
調(diào)用B項(xiàng)目
再調(diào)用A項(xiàng)目
由上可以看出,調(diào)用A,,A創(chuàng)建了session,,并存入屬性值。B中獲取到A的session,,并獲取屬性值,,修改屬性值;再次調(diào)用A,,A取得上一次的session,,并獲取修改后的屬性。不同項(xiàng)目實(shí)現(xiàn)了共享session,。
1.依此類推,,假如有多個(gè)項(xiàng)目,可將session的管理均存放與一個(gè)項(xiàng)目中,,其他項(xiàng)目只是變向的去獲取此項(xiàng)目中的session,便于維護(hù)與管理,;
2.此種情況下,可以簡(jiǎn)化操作,,避免了session的序列化,,使用更簡(jiǎn)便;
3.此方案遵從servlet的運(yùn)行機(jī)制,,極大的依賴session與cookie對(duì)應(yīng)關(guān)系,,所以cookie中存儲(chǔ)的信息就尤為重要,為防止JSESSIONID泄露而繞過登錄,,需要采取一些安全措施,,最好是使用https進(jìn)行加密。
而當(dāng)跨服務(wù)器環(huán)境時(shí),則需要對(duì)session進(jìn)行序列化存儲(chǔ),,可以保存到數(shù)據(jù)庫或其他的地方,,進(jìn)行統(tǒng)一管理,原理與此類似,。
1.最簡(jiǎn)便的就是修改session的生命周期,,雖然會(huì)浪費(fèi)一些資源,但處理大多數(shù)情況是足夠了,;
2.優(yōu)化方案就將session token化,將口令存儲(chǔ)于cookie中,,根據(jù)口令獲取用戶登錄權(quán)限,。需要注意的是token的一些加密及防竊取設(shè)置