JWT鑒權機制
1.JWT用于登錄身份驗證
2.用戶登錄成功后,后端通過JWT機制生成一個token,返回給客戶端
3.客戶端后續的每次請求都需要攜帶token,放在header的authorization中
4.后端從authorization中拿到token后,通過secretKey進行解密驗證省份
JWT生成的Token由三部分組成:header.payload.signature
**header:**主要是聲明采用的加密算法
? alg:指定生成signature采用的加密算法,默認是HS256
? typ:令牌類型,jwt
**payload:**載荷,消息體,這里存放實際的內容
? exp:設置過期時間
? uid:用戶uid
除了設置過期時間和用戶的uid,還可以添加自定義私有字段,使用base64url進行編碼組成JWT的第二部分
signature:
Signature = HMACSHA256(base64Url(header)+.+base64Url(payload),secretKey)
優點:
- json具有通用性,所以可以跨語言
- 組成簡單,字節占用小,便于傳輸
- 服務端無需保存會話信息,很容易進行水平擴展
- 一處生成,多處使用,可以在分布式系統中,解決單點登錄問題
- 可防護CSRF攻擊
缺點:
- payload部分僅僅是進行簡單編碼,所以只能用于存儲邏輯必需的非敏感信息
- 需要保護好加密密鑰,一旦泄露后果不堪設想
- 為避免token被劫持,最好使用https協議
共享登錄SSO
同域名下的單點登錄
cookie
的domain
屬性設置為當前域的父域,并且父域的cookie
會被子域所共享。path
屬性默認為web
應用的上下文路徑
利用 Cookie
的這個特點,沒錯,我們只需要將Cookie
的domain
屬性設置為父域的域名(主域名),同時將 Cookie
的path
屬性設置為根路徑,將 Session ID
(或 Token
)保存到父域中。這樣所有的子域應用就都可以訪問到這個Cookie
不過這要求應用系統的域名需建立在一個共同的主域名之下,如 tieba.baidu.com
和 map.baidu.com
,它們都建立在 baidu.com
這個主域名之下,那么它們就可以通過這種方式來實現單點登錄
不同域名下的單點登錄使用PostMessage
單點登錄完全用前端來實現,前端拿到Token之后,前端通過 iframe
+postMessage()
方式,將同一份 Token
寫入到了多個域下的 LocalStorage
中,前端每次在向后端發送請求之前,都會主動從 LocalStorage
中讀取Token
并在請求中攜帶,這樣就實現了同一份Token
被多個域所共享;此種實現方式完全由前端控制,幾乎不需要后端參與,同樣支持跨域
// 獲取 token
var token = result.data.token;// 動態創建一個不可見的iframe,在iframe中加載一個跨域HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 使用postMessage()方法將token傳遞給iframe
setTimeout(function () {iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {iframe.remove();
}, 6000);// 在這個iframe所加載的HTML中綁定一個事件監聽器,當事件被觸發時,把接收到的token數據寫入localStorage
window.addEventListener('message', function (event) {localStorage.setItem('token', event.data)
}, false);
認證中心來實現單點登錄
當用戶首次訪問時,需要在認證中心登錄:
1.當用戶訪問網站a.com下面的pageA頁面,
2.由于沒有登錄,則系統A會返回給瀏覽器302重定向,并帶上回調地址 www.sso.com?return_uri=a.com/pageA
,以便登錄后直接進入對應頁面。
3.重定向302之后,瀏覽器去訪問重定向地址,認證中心驗證未登錄,則展示form,提示用戶登錄
4.用戶在認證中心輸入賬號密碼,提交登錄
5.認證中心驗證賬號密碼有效,然后重定向 a.com?ticket=123
帶上授權碼 ticket
,并將認證中心 sso.com
的登錄態寫入 Cookie
6.在 a.com
服務器中,拿著 ticket
向認證中心確認,授權碼 ticket
真實有效。
7.驗證成功后,服務器將登錄信息寫入 Cookie
(此時客戶端有 2 個 Cookie
分別存有 a.com
和 sso.com
的登錄態)
前端常見登錄實現方案 + 單點登錄方案 - 掘金 (juejin.cn)