參考:
https://www.jianshu.com/p/75edcc05acfd(單點登錄(SSO)看這一篇就夠了)
https://blog.csdn.net/xiaoguan_liu/article/details/91492110(什么是單點登錄:原理與實現簡介)
1,不同域下的單點登錄,其實比較復雜;
2,需要注意:http協議的重定向其實都是瀏覽器重新發起的請求;和后台異步請求是不一樣的;
3,post跳轉只能借助表單
一,用戶登錄擠出
1,session機制時
//1,用戶登錄后 S[session_id1] = userData; G[user_id]=session_id1; //2,用戶在其他終端登錄 S[session_id2] = userData; G[user_id]=session_id2; S[session_id1=[state=>'已登出']; //3,用戶在之前的終端繼續訪問 請求驗證用戶信息,發現S[session_id1]已登出 提示客戶端在另一台設備登
2,token機制時
//1,用戶登錄后 userData生成token1; G[user_id]=token1; //2,用戶在其他終端登錄 userData生成token2; G[user_id]=toke2;#token被修改 //3,用戶在之前的終端繼續訪問 token1 解析 userData; 發現 token 不等於 G[user_id] ; 提示用戶已登出
二,多系統下單點登
1,同域下的單點登錄
相關知識:
1,我們在設置Cookie時,只能設置頂域和自己的域,不能設置其他的域。
2,session共享
解決2個問題:
- Cookie是不能跨域的,我們Cookie的domain屬性是sso.a.com,在給app1.a.com和app2.a.com發送請求是帶不上的。
- sso、app1和app2是不同的應用,它們的session存在自己的應用內,是不共享的。
//1
針對第一個問題,sso登錄以后,可以將Cookie的域設置為頂域
這樣所有子域的系統都可以訪問到頂域的Cookie。
//2
共享Session的解決方案
同域下單點登出:
登出后需要把session_id刪除,則對應的cookie失效,需要重新登錄和設置cookie
2,不同域下的單點登錄
具體流程如下:
1,用戶訪問app系統,app系統是需要登錄的,但用戶現在沒有登錄。
2,跳轉(重定向:帶上url參數)到CAS server,即SSO登錄系統,以后圖中的CAS Server我們統一叫做SSO系統。
SSO系統也沒有登錄,彈出用戶登錄頁。
3,用戶填寫用戶名、密碼,SSO系統進行認證后,將登錄狀態寫入SSO的session,瀏覽器(Browser)中寫入SSO域下的Cookie。(全局會話)
4,SSO系統登錄完成后會生成一個ST(Service Ticket),然后跳轉(重定向:根據url參)到app系統,同時將ST作為參數傳遞給app系統。
5,app系統拿到ST后,從后台向SSO發送請求,驗證ST是否有效。
6,驗證通過后,app系統將登錄狀態寫入session並設置app域下的Cookie。(局部會話)
1,用戶訪問app2系統,app2系統沒有登錄,跳轉(重定向:帶上url2)到SSO。#用戶此時訪問的是SSO系統,重定向瀏覽器會帶上SSO域的Cookie(變成全局會話)
2,由於SSO已經登錄了,不需要重新登錄認證。(SSO怎么知道已經登錄了?)
3,SSO生成ST,瀏覽器跳轉(重定向:根據url2參數)到app2系統,並將ST作為參數傳遞給app2。
4,app2拿到ST,后台訪問SSO,驗證ST是否有效。
5,驗證成功后,app2將登錄狀態寫入session,並在app2域下寫入Cookie。(局部會話)
這樣,app2系統不需要走登錄流程,就已經是登錄了。SSO,app和app2在不同的域,它們之間的session不共享也是沒問題的。
登出的問題
1,可以各自登出
銷毀各自的登錄態
2,單點登出
銷毀sso的登錄態
1,app下請求退出,app取出令牌ST,像SSO系統發出注銷請求(重定向) 2,SSO系統校驗令牌,通過ST解析出user_id, 銷毀user_id對應的全局會話(也就相應的session) 3,取出user_id對應的各個子系統的令牌ST,並銷毀 4,像各個子系統發出注銷user_id的注銷請求,銷毀各個局部會話(異步)
5,重定向的SSO的登錄頁面