泰漲知識 | 請求跨域 Session不共享?你遇到過這種情形嗎?

在JavaEE開發(fā)中,我們經(jīng)常使用SpringMVC或SpringBoot框架進(jìn)行后端開發(fā),在傳統(tǒng)的J2EE項目中,我們經(jīng)常采用MVC的設(shè)計模式完成項目框架的搭建,那我們從MVC模式進(jìn)入今天的問題。
MVC模式是如何的?
MVC設(shè)計模式是經(jīng)典的程序項目設(shè)計模式,M代表的是業(yè)務(wù)模型,V代表的是用戶視圖,C代表的是控制器,其使用MVC的設(shè)計模式目的是為了分離項目中會耦合的代碼部分,讓我們的后端代碼各司其職,程序員只需要了解模塊間的協(xié)調(diào)關(guān)系,注重業(yè)務(wù)邏輯的代碼實現(xiàn)就可以完成后端程序的開發(fā)了。MVC模式流程圖如下:

那Session在項目中是干啥呢?
Session是服務(wù)端會話存儲技術(shù),我們在后端開發(fā)中我們會將登錄用戶的信息保存到session中,如果用戶長時間或規(guī)定時間內(nèi)沒有操作,session就會過期從而讓系統(tǒng)回到登錄頁面。
Session主要存儲的內(nèi)容:
登錄用戶的信息作用:主頁展示登錄人、CURD操作攜帶用戶鑒權(quán)
系統(tǒng)相關(guān)信息:在多租戶項目中,可能需要復(fù)雜的數(shù)據(jù)權(quán)限鑒權(quán),也會在登錄的時候攜帶
什么是跨域?
這個原因來自于瀏覽器的同源策略安全限制, 同源策略會阻止一個域的javascript腳本和另外一個域的內(nèi)容進(jìn)行交互。當(dāng)我們使用ajax或者axios進(jìn)行http訪問時,非同源內(nèi)容就會出現(xiàn)跨域請求問題。錯誤圖如下:

04在開發(fā)中為何會跨域?
在傳統(tǒng)的開發(fā)中,在MVC框架中,View層技術(shù)一般會使用jsp、html、freemarker、thymeleaf技術(shù)完成,但是他們的源碼文件必須和項目框架文件在同一個目錄下才能實現(xiàn)視圖的解析,從而會出現(xiàn)耦合的效果。
從而MVVM框架出現(xiàn),實現(xiàn)了前后端的完全分離,以vue.js為例的技術(shù),實現(xiàn)前端是一個服務(wù)通過axios訪問服務(wù)端,從而達(dá)到前后端物理層面的分離,但是在這種情況下就會出現(xiàn)不同源的情況。
vue與服務(wù)端交互:

當(dāng)前端服務(wù)與后端服務(wù)不同源,但是在axios請求中會出現(xiàn)腳本的代理請求,就會出現(xiàn)非同源跨域問題。
跨域的簡單判斷
一個域名的組成由:協(xié)議、子域名、主域名、端口和資源地址組成;當(dāng)協(xié)議、子域名、主域名、端口號中任意一個不相同,都算作不同域,當(dāng)他們相互出現(xiàn)請求就會“跨域”。
跨域的解決


這樣我們前端的請求就再也不會跨域了,因為我們通過代理完成。
跨域解決了,那Session怎么辦?
session是保存在服務(wù)器端,理論上是沒有是沒有限制,只要內(nèi)存夠大。瀏覽器第一次訪問服務(wù)器時會創(chuàng)建一個session對象并返回一個JSESSIONID=ID的值,創(chuàng)建一個Cookie對象key為JSSIONID,value為ID的值,將這個Cookie寫回瀏覽器,瀏覽器第二次訪問服務(wù)器時攜帶Cookie信息JSESSIONID=ID的值,如果該JSESSIONID的session已經(jīng)銷毀,那么會重新創(chuàng)建一個新的session再返回一個新的JSESSIONID通過Cookie返回到瀏覽器針對一個web項目,一個瀏覽器是共享一個session,就算有兩個web項目部署在同一個服務(wù)器上,針對兩個項目的session是不同的。
但是在跨域的請求中,Session無法判別來自客戶端的cookie和SessionID,他們每次個不相同,所服務(wù)端數(shù)據(jù)存儲就得換一個思路實現(xiàn),使用Redis緩存實現(xiàn)。

那我們就開始吧!
安裝Redis后,在服務(wù)中配置Redis相關(guān)內(nèi)容,此處以Springboot為例,集成Redis緩存。

ok,完成之后我們設(shè)計一下資源驗證問題:
每個客戶端都有一個唯一的id描述我是一個獨立的客戶端;
客戶端id可以作為存儲Redis的key,value存儲客戶端的用戶數(shù)據(jù);
需要取出驗證必須要客戶端提供唯一id;
總結(jié)流程
首先獲取驗證碼發(fā)起的請求中要攜帶客戶端唯一id;
通過客戶端唯一id為存儲Redis的key值,value為客戶端對應(yīng)的驗證碼;
在登錄接口中獲取客戶端的唯一id,獲取對應(yīng)的驗證碼進(jìn)行比較;
這樣,我們就用Redis模擬了會話的方式保存驗證碼了。
歡迎關(guān)注“泰克教育” 公眾號,查看更多信息