背景
密碼加密、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...