正常的登入
正常的是通過session
步驟:
- 使用者在浏覽器登入
- 背景鑒權,若登入成功,則把使用者資訊寫入session,servlet自動生成JSESSIONID 傳回浏覽器;
-
浏覽器把JSESSIONID 寫入cookie
說明:cookie是浏覽器的存儲檔案,存儲的隻是JSESSIONID,而不是使用者資訊;
JSESSIONID 隻是一個鈎子,使用者資訊其實存儲在伺服器端.
比如我在浏覽器登入之後,重新打開一個标簽頁,輸入相同的位址,仍然是登入狀态,因為标簽頁共享cookie.
也就是說我隻要擷取到JSESSIONID ,就可以擷取使用者隐私資訊,比如除使用者名以外的其他資訊(密碼,姓名,年齡等).也可以做一些敏感操作,比如修改密碼
浏覽器發送請求時會帶上cookie
這樣伺服器端才知道是否登入過:

例如,我擷取到JSESSIONID 之後,使用HTTP模拟發送請求:
伺服器端是如何判斷是否登入
/***
* 判斷是否已登入
* @param user2
* @return
*/
public static boolean isLogined(User user2,String loginFlag){
if(ValueWidget.isNullOrEmpty(user2)||ValueWidget.isNullOrEmpty(user2.getUsername())
||loginFlag == null
||( !loginFlag.equalsIgnoreCase(Constant2.FLAG_LOGIN_SUCCESS))){
return false;
}else{
return true;
}
}
/***
* 判斷是否已登入
* @param session
* @return
*/
public static boolean isLogined(HttpSession session){
String loginFlag = (String) session
.getAttribute(Constant2.SESSION_KEY_LOGINED_FLAG);
User user2 = (User) session.getAttribute(Constant2.SESSION_KEY_LOGINED_USER);
return isLogined(user2,loginFlag);
}
通過 cookie 實作單點登入
-
登入之前,會向伺服器請求一個随機token,同時傳回cookie,例如:
CCC=63314c585041e889766fec6657879c; Expires=Mon, 21-Sep-2015 06:48:27 GMT; Path=/
- 登入時帶上這個cookie(即CCC=63314c585041e889766fec6657879c)
-
伺服器鑒權,登入成功之後,把登入憑證和CCC 綁定,
即伺服器可以通過CCC 判斷是否登入,也可以通過CCC 擷取使用者敏感資訊.
這樣的話,隻要登入過,使用者不主動清除cookie,那就一直是登入狀态.
如果使用者主動清除了cookie,那就不是登入狀态了
詳細流程,邏輯
(1)登入前,浏覽器先向認證伺服器請求一個OTP,認證伺服器傳回OTP,同時傳回一個cookie給浏覽器;
(2)認證伺服器把OTP 和CCC(cookie) 挂鈎;
(3)登入時連同帶上OTP
(4)若登入成功,則認證伺服器傳回登入憑證(access token)給浏覽器;
(5)認證伺服器把CCC 和登入憑證挂鈎;
(6)通過CCC 可以判斷使用者是否有權限.
是以,
(a)可以通過CCC 擷取登入憑證
(b)也可以通過OTP 擷取登入憑證
根本原因:伺服器把OTP 和CCC(cookie) 挂鈎
那麼CCC記在什麼地方?
浏覽器
擷取OTP的接口傳回:
效果:
A和B是同一個公司的應用,
在同一個浏覽器中登入了應用A ,就可以在該浏覽器中直接通路應用B,而不用重新登入.
具體實作原理:
1,登入之前通路 認證系統的動态密碼接口,擷取動态密碼:auth_token
同時會傳回cookie:CCC ,目的:把浏覽器和 auth_token 挂鈎
等浏覽器通路其他應用時,把該CCC帶過去.
2,登入時參數包括(1)中傳回的auth_token ;
3,通路應用B 時,浏覽器會把cookie中的CCC傳過去,應用B 拿到之後,給認證系統認證,判斷是否登入;
若認證通過,則傳回使用者資訊
單點登入的目的
同一個公司的應用,隻需要登入一次。
比如我登入了阿裡雲,再打開淘寶 ,天貓或釘釘就不用重複登入(輸入使用者名和密碼)。
具體場景(Web)
小明登入了 Web應用A,再進入Web應用B時,不用重新輸入使用者名和密碼,就自動登入了。
問題:應用A和應用B要擁有相同的父域名嗎?
不用!!!
阿裡雲 和淘寶的域名就不一樣
具體實作(基于 cookie)
otp :one time password 就是一次一密
認證中心接口
接口一:jsonp接口,擷取 otp
請求方式:jsonp
擷取 otp,同時可以判斷是否已登入
http://auth.xxx.com/authentication/otp.jsonp?callbk=callbkMethod&clientId=應用的clientId
傳回
{
"isLogined":true,
"otp":"433u23"
}
注意:jsonp 接口隻需要 clientId,不需要 secret
接口二:使用 otp登入
請求方式:post
http://auth.xxx.com/authentication/login.json
/>參數:
username:
password:
otp:接口一擷取的 otp
imgCode:圖形驗證碼
傳回:
"access_token":"",
"refresh_token":"",
"timeout":12000
...
接口三:opt 換取 access_token
http://auth.xxx.com/authentication/token.json?secret=應用的secret&clientId=應用的clientId&opt=433u23
認證中心的作用
- 判斷是否已登入;
- otp 換access_token