前後端分離 關於登入狀態那些事

2021-09-24 19:18:14 字數 2742 閱讀 3102

背景

密碼加密、cookie、session、token、jwt等。

我們看一下傳統的做法,前後端統一在乙個服務中:

如圖所示,邏輯處理和頁面放在乙個服務中,使用者輸入使用者名稱、密碼後,後台服務在session中設定登入狀態,和使用者的一些基本資訊,

然後將響應(response)返回到瀏覽器(browser),並設定cookie。下次使用者在這個瀏覽器(browser)中,再次

訪問服務時,請求中會帶上這個cookie,服務端根據這個cookie就能找到對應的session,從session中取得使用者的資訊,從而

維持了使用者的登入狀態。這種機制被稱作cookie-session機制。

近幾年,隨著前後端分離的流行,我們的專案結構也發生了變化,如下圖:

我們訪問乙個**時,先去請求靜態服務,拿到頁面後,再非同步去後台請求資料,最後渲染成我們看到的帶有資料的**。在這種結構下,

我們的登入狀態怎麼維持呢?上面的cookie-session機制還適不適用?

這裡又分兩種情況,服務a和服務b在同一域下,服務a和服務b在不同域下。在詳細介紹之前,我們先普及一下瀏覽器的同源策略。

同源策略

同源策略是瀏覽器保證安全的基礎,它的含義是指,a網頁設定的 cookie,b網頁不能開啟,除非這兩個網頁同源。

所謂同源是指:

協議相同

網域名稱相同

埠相同例如:協議是http,網域名稱是www.a.com,埠是80。只要這3個相同,我們就可以在請求(request)時帶上cookie,

在響應(response)時設定cookie。

同域下的前後端分離

我們了解了瀏覽器的同源策略,接下來就看一看同域下的前後端分離,首先看服務端能不能設定cookie,具體**如下:

後端**:

我們設定cookie的path為根目錄/,以便在該域的所有路徑下都能看到這個cookie。

前端**:

我們在瀏覽器訪問訪問前先設定hosts,將www.a.com指向我們本機。訪問結果如圖所示:

我們可以看到伺服器成功設定了cookie。然後我們再看看同域下,非同步請求能不能帶上cookie,**如下:

後端**:

前端**如下:

訪問結果如圖所示:

再看看後台列印的日誌:

name:test-----value:same

同域下,非同步請求時,cookie也能帶到服務端。

所以,我們在做前後端分離時,前端和後端部署在同一域下,滿足瀏覽器的同源策略,登入不需要做特殊的處理。

不同域下的前後端分離

不同域下,我們的響應(response)能不能設定cookie呢?請求時能不能帶上cookie呢?我們實驗結果如下,這裡就不給大家貼**了。

由於我們在a.com域下的頁面跨域訪問b.com的服務,b.com的服務不能設定cookie。

如果b.com域下有cookie,我們在a.com域下的頁面跨域訪問b.com的服務,能不能把b.com的cookie帶上嗎?答案是也帶不上。那麼我們怎麼解決

跨域問題呢?

jsonp解決跨域

jsonp的原理我們可以在維基百科上檢視,上面寫的很清楚,我們不做過多的介紹。我們改造介面,

在每個介面上增加callback引數:

如果callback引數不為空,將返回js函式。前端改造如下:

設定cookie頁面改造如下:

請求cookie時改造如下:

所有的請求都加了callback引數,請求的結果如下:

很神奇吧!我們設定了b.com域下的cookie。如果想知道為什麼?還是看一看jsonp的原理吧。我們再訪問第二個頁面,看看cookie能不能

傳到服務。後台列印日誌為:

name:test-----value:same

好了,不同域下的前後端分離,可以通過jsonp跨域,從而保持登入狀態。但是,jsonp本身沒有跨域安全規範,一般都是後端進行安全限制,

處理不當很容易造成安全問題。

cors解決跨域

cors是乙個w3c標準,全稱是跨域資源共享(cross-origin resource sharing)。cors需要瀏覽器和伺服器同時支援。目前,所有瀏覽器都支援該功能,ie瀏覽器不能低於ie10。

整個cors通訊過程,都是瀏覽器自動完成,不需要使用者參與。對於開發者來說,cors通訊與同源的ajax通訊沒有差別,**完全一樣。

瀏覽器一旦發現ajax請求跨源,就會自動新增一些附加的頭資訊,有時還會多出一次附加的請求,但使用者不會有感覺。

如果想要詳細理解原理,請參考維基百科

cors請求預設不傳送cookie和http認證資訊。若要傳送cookie,瀏覽器和服務端都要做設定,咱們要解決的是跨域後的登入問題,所以要允許跨域傳送

cookie。

後端要設定允許跨域請求的域和允許設定和接受cookie。

我們通過@crossorigin註解允許跨域,origins設定了允許跨域請求的域,allowcredentials允許設定和接受cookie。

前端要設定允許傳送和接受cookie。

我們訪問頁面看一下效果。

沒有cookie嗎?別急,我們再從瀏覽器的設定裡看一下。

有cookie了,我們再看看訪問能不能帶上cookie,後台列印結果如下:

name:test-----value:same

我們使用cors,也解決了跨域。

總結前後端分離,基於cookie-session機制的登入總結如下

前後端同域——與普通登入沒有區別

前後端不同域

jsonp方式實現

cors方式實現

關於前後端分離

為什麼要前後端分離?記得大學時候剛開始接觸web開發時候,前端用的是html jsp,根本不懂得架構什麼的。直到畢業工作,入了第一家公司。趕上乙個專案,老框架的那種,有段時間我負責解bug。有些問題是頁面的問題,有些事dispatcher路徑沒有寫對,有些是引數格式不對。很煩的就是每次做完修改,都需...

關於API,前後端分離

而關於介面的規定,衍生出了一大堆問題,第一是關於空值的制定,是不輸出呢?還是輸出null,還是輸出 今天在除錯1688開放平台時,1688開放平台那邊出了兩套介面api給我們調,一套是舊的,用關鍵字deprecated標誌過時,而一套是新的,因為是最近才推出的吧。有點坑的是,新介面雖然變得簡潔了,但...

前後端分離下如何登入

1.1 http無狀態性 http是無狀態的,一次請求結束,連線斷開,下次伺服器再收到請求,它就不知道這個請求是哪個使用者發過來的。當然它知道是哪個客戶端位址發過來的,但是對於我們的應用來說,我們是靠使用者來管理,而不是靠客戶端。所以對我們的應用而言,它是需要有狀態管理的,以便服務端能夠準確的知道h...