Session與Token認證機制 前后端分離下如何登錄


  字號

1 Web登錄涉及到知識點

1.1 HTTP無狀態性

HTTP是無狀態的,一次請求結束,連接斷開,下次服務器再收到請求,它就不知道這個請求是哪個用戶發過來的。當然它知道是哪個客戶端地址發過來的,但是對於我們的應用來說,我們是靠用戶來管理,而不是靠客戶端。所以對我們的應用而言,它是需要有狀態管理的,以便服務端能夠准確的知道http請求是哪個用戶發起的,從而判斷該用戶是否有權限繼續這個請求。這個過程就是常說的會話管理。

1.2 登錄流程

登錄的基本流程

 

2 同域登錄

目前大多數Web應用采用前后端分離方式進行開發。所以前端網站或應用都屬於SPA(Single Page Application)。如果前端,后台API部署在同域下,不存在跨域的情況,登錄方式相對簡單。

 

2.1 基於Session登錄

服務器端使用Session技術,瀏覽器端使用Cookie技術。


 

1.服務端session是用戶第一次訪問應用時,服務器就會創建的對象,代表用戶的一次會話過程,可以用來存放數據。服務器為每一個session都分配一個唯一的sessionid,以保證每個用戶都有一個不同的session對象。
 2.服務器在創建完session后,會把sessionid通過cookie返回給用戶所在的瀏覽器,這樣當用戶第二次及以后向服務器發送請求的時候,就會通過cookie把sessionid傳回給服務器,以便服務器能夠根據sessionid找到與該用戶對應的session對象。
3.session通常有失效時間的設定,比如2個小時。當失效時間到,服務器會銷毀之前的session,並創建新的session返回給用戶。但是只要用戶在失效時間內,有發送新的請求給服務器,通常服務器都會把他對應的session的失效時間根據當前的請求時間再延長2個小時。
4.session在一開始並不具備會話管理的作用。它只有在用戶登錄認證成功之后,並且往sesssion對象里面放入了用戶登錄成功的憑證,才能用來管理會話。管理會話的邏輯也很簡單,只要拿到用戶的session對象,看它里面有沒有登錄成功的憑證,就能判斷這個用戶是否已經登錄。當用戶主動退出的時候,會把它的session對象里的登錄憑證清掉。所以在用戶登錄前或退出后或者session對象失效時,肯定都是拿不到需要的登錄憑證的。
 

2.2 基於Token登錄
 

 

 1.用戶在瀏覽器中輸入用戶和密碼,后台服務器通過加密或者其他邏輯,生成一個Token。
 2.前端獲取到Token,存儲到cookie或者localStorage中,在接下來的請求中,將token通過url參數或者HTTP Header頭部傳入到服務器
 3.服務器獲取token值,通過查找數據庫判斷當前token是否有效

基於Token登錄,而且可以用於第三方單點登錄的OAuth2.0更適合。可以參考網址:理解OAuth 2.0
 

 

3 Cookie的傳輸

簡單地說,cookie 就是瀏覽器儲存在用戶電腦上的一小段文本文件。cookie 是純文本格式,不包含任何可執行的代碼。一個 Web 頁面或服務器告知瀏覽器按照一定規范來儲存這些信息,並在隨后的請求中將這些信息發送至服務器,Web 服務器就可以使用這些信息來識別不同的用戶。大多數需要登錄的網站在用戶驗證成功之后都會設置一個 cookie,只要這個 cookie 存在並可以,用戶就可以自由瀏覽這個網站的任意頁面。再次說明,cookie 只包含數據,就其本身而言並不有害。

同域情況下,Cookie會在隨后的請求中攜帶

 

4 跨域登錄

跨越定義 :由於瀏覽器同源策略,凡是發送請求的url的協議(http和https)、域名(www.example.com,about.example.com)、端口(8010和8020)三者之間任意一個與當前頁面地址不同則視為跨域。

 

4.1 解決同源策略

基於Session和Token登錄都要解決。

 

瀏覽器的同源策略

如果使用同域的方法,那么瀏覽器會拋出如下錯誤。demo示例,前端運行在http://localhost:8010/login.html,后台運行在http://localhost:8020/api/login.php

https://img1.mukewang.com/5b7950be00017f8212560130.jpg

需要在服務器端設置Header,以PHP為例:

header('Access-Control-Allow-Origin: http://localhost:8010');

設置完成之后,可以發送請求了,登錄成功之后跳轉到home.html還是顯示未登錄,會跳轉到login.html頁面

 

4.2 解決請求帶上Cookie信息

基於Session登錄才需要,因為相關信息是通過Cookie傳入,如果是通過url傳入,也不需要解決這個。基於Token,后續請求攜帶token都是通過header里面的字段,所以也不需要解決這個。

跨越情況下,瀏覽器此時不會默認在后續請求里面攜帶上Cookie信息,這個時候前后端都需要設置。以jQueryPHP為列。

前端jQuery代碼
Ajax請求中葯設置xhrFields

xhrFields: {        withCredentials: true
    }

完整代碼如下:

$.ajax({
    url: "http://localhost:8020/api/login.php",
    type: "POST",
    data: {
        username: $("#username").val(),
        password: $("#password").val()
    },
    dataType: "json",
    xhrFields: {
        withCredentials: true
    }
}).done(function (response) {    debugger;
    $("#log").html(response.message);    window.location.href = "home.html";
}).fail(function (jqXHR, textStatus) {    console.log("Request failed: " + textStatus);
});

后端php代碼

/*需要設置這一行,接收傳入Credentials字段*/header('Access-Control-Allow-Credentials: true');  
header('Access-Control-Allow-Origin: http://localhost:8010');


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM