久久综合九色综合97婷婷-美女视频黄频a免费-精品日本一区二区三区在线观看-日韩中文无码有码免费视频-亚洲中文字幕无码专区-扒开双腿疯狂进出爽爽爽动态照片-国产乱理伦片在线观看夜-高清极品美女毛茸茸-欧美寡妇性猛交XXX-国产亚洲精品99在线播放-日韩美女毛片又爽又大毛片,99久久久无码国产精品9,国产成a人片在线观看视频下载,欧美疯狂xxxx吞精视频

有趣生活

當(dāng)前位置:首頁>職場(chǎng)>后端的session怎么取出(說說你對(duì)Session的理解)

后端的session怎么取出(說說你對(duì)Session的理解)

發(fā)布時(shí)間:2024-01-24閱讀(16)

導(dǎo)讀作者:千里明月來源:https://my.oschina.net/mingyuelab/blog/2986928#簡(jiǎn)介session(會(huì)話),其實(shí)是一個(gè)容易....

作者:千里明月 來源:https://my.oschina.net/mingyuelab/blog/2986928

# 簡(jiǎn)介

session(會(huì)話),其實(shí)是一個(gè)容易讓人誤解的詞。它總跟web系統(tǒng)的會(huì)話掛鉤,利用session,javaweb項(xiàng)目實(shí)現(xiàn)了登錄狀態(tài)的控制。坊間流傳,關(guān)閉瀏覽器,就是關(guān)閉了web系統(tǒng)的會(huì)話。

其實(shí)瀏覽器對(duì)于會(huì)話有自己的定義,而web系統(tǒng)對(duì)于會(huì)話也有自己的定義。在tomcat中,Session通常是指實(shí)現(xiàn)了HttpSession接口的實(shí)現(xiàn)類。并且不存在關(guān)閉瀏覽器就會(huì)關(guān)閉tomcat的HttpSession這種狀況。

session本身并不難,如果只是做登錄校驗(yàn)之類的功能,并不需要深入了解,但難的是session和cookie的結(jié)合使用,在不同情況下瀏覽器對(duì)cookie的控制行為所涉及到的諸多細(xì)節(jié),我搜查了很多資料,查看過tomcat源碼,亦是沒有找到全面的概述。

當(dāng)然我并未看過、也不知道去哪里看比較全面的關(guān)于瀏覽器對(duì)cookie的控制資料,如果有知道的大神,還望留言鏈接。本文題目,之所以說是探討,而不是了解或者介紹,因?yàn)槲易约阂部ㄔ诹四硞€(gè)點(diǎn)上,由于時(shí)間關(guān)系,我不能花太多時(shí)間去研究,但又不忍心就此放棄,所以先記錄下來,日后有機(jī)會(huì)再研究,這期間如有大神指點(diǎn),也許能讓我茅塞頓開。

# Session本質(zhì)

我用的是javaweb項(xiàng)目,因此這里的session特指HttpSession。先來看下tomcat源碼中對(duì)session的設(shè)計(jì),在org.apache.catalina.session包下,有如下設(shè)計(jì)。

后端的session怎么取出(說說你對(duì)Session的理解)(1)

平時(shí)所用到的HttpSession的實(shí)現(xiàn)類就是這個(gè)standardSession。但是所獲取的HttpSession實(shí)例確是外觀類StandardSessionFacade,其屏蔽了許多方法,但也增強(qiáng)了安全性。

HttpSession提供了一些方法,來控制session或者獲取session的狀態(tài),如獲取session的id,獲取session的創(chuàng)建時(shí)間,設(shè)置session的attribute,使session失效等。值得一提的是session的attribute其實(shí)是一個(gè)線程安全的hashMap。

/** * The collection of user data attributes associated with this Session. */ protected ConcurrentMap<String, Object> attributes = new ConcurrentHashMap<>();

但是,創(chuàng)建session、根據(jù)id獲取session的方法并不在這里,而是在一個(gè)管理器中,其設(shè)計(jì)如下。

后端的session怎么取出(說說你對(duì)Session的理解)(2)

ManagerBase是實(shí)現(xiàn)了Manager接口的抽象類,實(shí)現(xiàn)了管理session的功能。其實(shí)現(xiàn)子類PersistentManagerBase拓展了將session持久化的功能。但是這里不需要講到其子類。

看ManagerBase中的一段代碼。

/** * The set of currently active Sessions for this Manager, keyed by * session identifier. */ protected Map<String, Session> sessions = new ConcurrentHashMap<>();

由此可知,所謂的session,其實(shí)就是一個(gè)用線程安全的hashMap存儲(chǔ)起來的實(shí)現(xiàn)了Session接口的standardSession對(duì)象,在hashmap中以其id為key,自身為value。

再看獲取session的方法,一目了然。

@Override public Session findSession(String id) throws IOException { if (id == null) { return null; } return sessions.get(id); }

最重要的是看其createSession方法。

后端的session怎么取出(說說你對(duì)Session的理解)(3)

這個(gè)方法是在什么時(shí)候調(diào)用的呢?當(dāng)瀏覽器訪問系統(tǒng)時(shí),request會(huì)解析請(qǐng)求中攜帶的jssesionid,用它去找到存在于應(yīng)用中的session,但是如果沒有找到,那么就會(huì)調(diào)用session的創(chuàng)建方法,并且生成一個(gè)新的jssessionid,返回session。

總而言之,session是存在于線程安全的map中的值,可以通過id找到,也可以使用invalidate方法銷毀,但絕不會(huì)是瀏覽器關(guān)閉,就能對(duì)它進(jìn)行銷毀的。

# Cookie 簡(jiǎn)介

提到session,那么cookie是不得不說的。至于cookie是什么,我就不多說了,大家都懂。直接看其內(nèi)容吧。

后端的session怎么取出(說說你對(duì)Session的理解)(4)

這是一次http請(qǐng)求中(http://localhost:8080/test1),包含的請(qǐng)求和響應(yīng)信息,是對(duì)一個(gè)系統(tǒng)的初次訪問,用的是谷歌瀏覽器。

請(qǐng)求頭中,包含的Cookie信息,并沒有上文提到的jsessionid, 那是因?yàn)檫@是對(duì)系統(tǒng)的初次訪問,系統(tǒng)還沒生成session。但是訪問之后,系統(tǒng)就會(huì)生成一個(gè)session,而且,會(huì)在響應(yīng)流中設(shè)置響應(yīng)頭Set-Cookie,其值為JESSIONID=xxx。這樣瀏覽器對(duì)localhost:8080和cookie的聯(lián)系就有了記憶,瀏覽器會(huì)將其存儲(chǔ)起來,可在調(diào)試工具中看到。

后端的session怎么取出(說說你對(duì)Session的理解)(5)

那么再次訪問http://localhost:8080/test1, 瀏覽器會(huì)主動(dòng)在請(qǐng)求頭添加包括jsession的cookie信息。

后端的session怎么取出(說說你對(duì)Session的理解)(6)

系統(tǒng)根據(jù)這個(gè)jsessionid找到session,也就不會(huì)在響應(yīng)頭中添加Set-Cookie信息。

這里說一下cookie中的兩個(gè)重要屬性。

  • domain表示的是cookie所在的域,默認(rèn)為請(qǐng)求的地址,如網(wǎng)址為www.test.com/test/test.aspx,那么domain默認(rèn)為www.test.com。而跨域訪問,如域A為t1.test.com,域B為t2.test.com,那么在域A生產(chǎn)一個(gè)令域A和域B都能訪問的cookie就要將該cookie的domain設(shè)置為.test.com;如果要在域A生產(chǎn)一個(gè)令域A不能訪問而域B能訪問的cookie就要將該cookie的domain設(shè)置為t2.test.com。
  • path表示cookie所在的目錄,默認(rèn)為/,就是根目錄。在同一個(gè)服務(wù)器上有目錄如下:/test/,/test/cd/,/test/dd/,現(xiàn)設(shè)一個(gè)cookie1的path為/test/,cookie2的path為/test/cd/,那么test下的所有頁面都可以訪問到cookie1,而/test/和/test/dd/的子頁面不能訪問cookie2。這是因?yàn)閏ookie能讓其path路徑下的頁面訪問。

# 疑點(diǎn)

下面,就該說下我的疑點(diǎn)了。

情況1

但是當(dāng)我在8081的一個(gè)方法中,重定向到8080的一個(gè)路徑時(shí),發(fā)現(xiàn)了奇怪的現(xiàn)象。

8081系統(tǒng)的方法如下。

@GetMapping("/test") public void get1(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); String id = session.getId(); System.out.println(id); response.sendRedirect("http://localhost:8080/test1"); }

8080系統(tǒng)的被重定向路徑如下。

@GetMapping("/test1") public void get11(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); String id = session.getId(); System.out.println(id); }

1、初次訪問localhost:8081/test 得到兩次請(qǐng)求的信息,一次是重定向的,一次是8080的。

后端的session怎么取出(說說你對(duì)Session的理解)(7)

這說明對(duì)8081系統(tǒng)的初次訪問,是沒有發(fā)送jsessionid信息的,而8081系統(tǒng)生成了一個(gè)id為CAAB6AED34716A0394705BDE8CAC0042的session并設(shè)置到了響應(yīng)頭,再次訪問8081時(shí)理應(yīng)會(huì)帶上這么一個(gè)id。

2、

后端的session怎么取出(說說你對(duì)Session的理解)(8)

這個(gè)對(duì)8080系統(tǒng)的請(qǐng)求中帶有jsessionid為CAAB6AED34716A0394705BDE8CAC0042的cookie信息,要知道,我們對(duì)8080的訪問也是初次的,那么為什么會(huì)帶上jsessionid呢?而且這個(gè)jsessionid明顯是在8081系統(tǒng)中生成并設(shè)置到響應(yīng)頭的的jsessionid。這個(gè)現(xiàn)象我用谷歌和edge瀏覽器分別嘗試過,都是這樣。那么是不是說明,瀏覽器把這個(gè)重定向到localhost:8080的請(qǐng)求當(dāng)成是同域的請(qǐng)求了 。

暫且放下這個(gè)疑惑,繼續(xù)往下驗(yàn)證。由于這個(gè)請(qǐng)求是對(duì)8080的系統(tǒng)的訪問,由于是初次訪問,系統(tǒng)根本沒有id為CAAB6AED34716A0394705BDE8CAC0042的session,因此只好生成一個(gè)新的session,在響應(yīng)頭中增加Set-Cookie。

3、

再次訪問localhost:8081/test,這時(shí)根據(jù)上文說的,“再次訪問8081時(shí)理應(yīng)會(huì)帶上這么一個(gè)id”,也就是在cookie中帶上JSESSION=CAAB6AED34716A0394705BDE8CAC0042, 但是,我發(fā)現(xiàn)它帶的卻是在系統(tǒng)8080中生成的BA0D2C939ADEC087C0A5F0C9B3354891 !!!

這就導(dǎo)致了8081找不到session又再次生成了一個(gè)新的session,循環(huán)往復(fù),每次對(duì)8081的訪問都會(huì)產(chǎn)生新的session。而這情況,我覺得很明顯,是瀏覽器把對(duì)8081的訪問當(dāng)成是于8080同源的了。

基于此推論,我模擬了另一種實(shí)驗(yàn)情況,去掉重定向的功能:

情況2

在本地開兩個(gè)web服務(wù),端口分別是8080,8081。

localhost:8081/test

@GetMapping("/test") public void get1(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); String id = session.getId(); System.out.println(id); }

localhost:8080/test1

@GetMapping("/test1") public void get11(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); String id = session.getId(); System.out.println(id); }

1、第一次訪問8081/test

后端的session怎么取出(說說你對(duì)Session的理解)(9)

沒有cookie,服務(wù)器設(shè)置set-cookie,正常。

2、第二次訪問8081/test

后端的session怎么取出(說說你對(duì)Session的理解)(10)

cookie與上次的set-cookie一致,正常。

3、第一次訪問8080/test1

后端的session怎么取出(說說你對(duì)Session的理解)(11)

瀏覽器把8081/test的cookie發(fā)過去了。8080的服務(wù)器找不到這個(gè)jsessionid,又重新設(shè)置了jsessionid,等到再次訪問8081/test時(shí),大家也能猜到會(huì)發(fā)生什么了吧。

# 推論

至此,我斗膽推論,瀏覽器會(huì)對(duì)同一ip不同端口的服務(wù)訪問認(rèn)定是可以進(jìn)行cookie共享的,兩個(gè)cookie的domain是一致的。而這種cookie的截圖也一定程度上印證了我的想法。

后端的session怎么取出(說說你對(duì)Session的理解)(12)

cookie的domain似乎只認(rèn)定域名,無關(guān)端口。

但是根據(jù)瀏覽器的同源策略,同域名不同端口的訪問也應(yīng)該是跨域的啊。除非瀏覽器的域跟cookie的domain在概念上是有區(qū)別的,對(duì)于這點(diǎn),我沒找到確切的官方資料,但網(wǎng)上大神是這么說的。

解決方案

基于上面的未查閱官方資料而做出的不嚴(yán)謹(jǐn)?shù)耐普摚蚁耄灰耆苊馔虻那闆r就可以避開這個(gè)問題。于是我把8081和8080系統(tǒng)分別部署在兩個(gè)機(jī)器上。由于不同ip,這樣無論如何,兩個(gè)cookie都不會(huì)是同domain的了。果然,結(jié)果是沒有問題的。

不足

雖然這個(gè)解決方案避開了同域的問題,但是沒有徹底解決,畢竟同域的系統(tǒng)相互之間的訪問也是有必要的,為此希望能獲得更多的建議或者資料,補(bǔ)充這方面知識(shí)的不足,讓我徹底解決這個(gè)問題。


這里,東哥來做個(gè)總結(jié)吧,文中的作者卡在了同源策略和跨域的問題,本文描述的的問題是屬于跨域的問題。

同源指的是協(xié)議、域名、端口都相同(可通過題圖來理解此概念)。瀏覽器之所以要制定同源策略,其目的便是防止頁面加載來源不明的腳本,而被黑客操作。

而跨域指的是域名不同,跟端口沒有關(guān)系。比如常用的JSONP技術(shù),便是利用了<script>標(biāo)簽的跨域能力來訪問跨域數(shù)據(jù)。說到這里,又比如 SSO 單點(diǎn)登錄技術(shù)有那些實(shí)現(xiàn)手段呢?大家可以想象,這些技術(shù)會(huì)存在什么安全問題,又該怎么防御呢?歡迎在留言區(qū)討論。

TAGS標(biāo)簽:  后端  session  怎么  取出  說說  后端的session

歡迎分享轉(zhuǎn)載→http://m.avcorse.com/read-232409.html

Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號(hào)-5 TXT地圖HTML地圖XML地圖