国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

什么是單點登錄(SSO)

番茄西紅柿 / 3499人閱讀

摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。

前言

只有光頭才能變強。

文本已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen…

在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就一直躺在我的收藏夾里邊:

在前陣子有個讀者來我這投稿,是使用JWT實現單點登錄的(但是文章中并沒有介紹什么是單點登錄),所以我覺得是時候來整理一下了。

簡單代碼實現JWT(json web token)完成SSO單點登錄

一、什么是單點登錄?

單點登錄的英文名叫做:Single Sign On(簡稱SSO)。

初學/以前的時候,一般我們就單系統,所有的功能都在同一個系統上。

后來,我們為了合理利用資源和降低耦合性,于是把單系統拆分成多個子系統。

回顧:分布式基礎知識

比如阿里系的淘寶和天貓,很明顯地我們可以知道這是兩個系統,但是你在使用的時候,登錄了天貓,淘寶也會自動登錄。

簡單來說,單點登錄就是在多個系統中,用戶只需一次登錄,各個系統即可感知該用戶已經登錄。

二、回顧單系統登錄

在我初學JavaWeb的時候,登錄和注冊是我做得最多的一個功能了(初學Servlet的時候做過、學SpringMVC的時候做過、跟著做項目的時候做過…),反正我也數不清我做了多少次登錄和注冊的功能了...這里簡單講述一下我們初學時是怎么做登錄功能的。

眾所周知,HTTP是無狀態的協議,這意味著服務器無法確認用戶的信息。于是乎,W3C就提出了:給每一個用戶都發一個通行證,無論誰訪問的時候都需要攜帶通行證,這樣服務器就可以從通行證上確認用戶的信息。通行證就是Cookie

如果說Cookie是檢查用戶身上的”通行證“來確認用戶的身份,那么Session就是通過檢查服務器上的”客戶明細表“來確認用戶的身份的。Session相當于在服務器中建立了一份“客戶明細表”

HTTP協議是無狀態的,Session不能依據HTTP連接來判斷是否為同一個用戶。于是乎:服務器向用戶瀏覽器發送了一個名為JESSIONID的Cookie,它的值是Session的id值。其實Session是依據Cookie來識別是否是同一個用戶

所以,一般我們單系統實現登錄會這樣做:

登錄:將用戶信息保存在Session對象中

如果在Session對象中能查到,說明已經登錄

如果在Session對象中查不到,說明沒登錄(或者已經退出了登錄)

注銷(退出登錄):從Session中刪除用戶的信息

記住我(關閉掉瀏覽器后,重新打開瀏覽器還能保持登錄狀態):配合Cookie來用

我之前Demo的代碼,可以參考一下:

 /**
 * 用戶登陸
 */
@PostMapping(value = "/user/session", produces = {"application/json;charset=UTF-8"})
public Result login(String mobileNo, String password, String inputCaptcha, HttpSession session, HttpServletResponse response) {

    //判斷驗證碼是否正確
    if (WebUtils.validateCaptcha(inputCaptcha, "captcha", session)) {

        //判斷有沒有該用戶
        User user = userService.userLogin(mobileNo, password);
        if (user != null) {
            /*設置自動登陸,一個星期.  將token保存在數據庫中*/
            String loginToken = WebUtils.md5(new Date().toString() + session.getId());
            user.setLoginToken(loginToken);
            User user1 = userService.userUpload(user);

            session.setAttribute("user", user1);

            CookieUtil.addCookie(response,"loginToken",loginToken,604800);

            return ResultUtil.success(user1);

        } else {
            return ResultUtil.error(ResultEnum.LOGIN_ERROR);
        }
    } else {
        return ResultUtil.error(ResultEnum.CAPTCHA_ERROR);
    }

}

/**
 * 用戶退出
 */
@DeleteMapping(value = "/session", produces = {"application/json;charset=UTF-8"})
public Result logout(HttpSession session,HttpServletRequest request,HttpServletResponse response ) {

    //刪除session和cookie
    session.removeAttribute("user");

    CookieUtil.clearCookie(request, response, "loginToken");

    return ResultUtil.success();
}
/**
* @author ozc
* @version 1.0
* 

* 攔截器;實現自動登陸功能 */ public class UserInterceptor implements HandlerInterceptor { @Autowired private UserService userService; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { User sessionUser = (User) request.getSession().getAttribute("user"); // 已經登陸了,放行 if (sessionUser != null) { return true; } else { //得到帶過來cookie是否存在 String loginToken = CookieUtil.findCookieByName(request, "loginToken"); if (StringUtils.isNotBlank(loginToken)) { //到數據庫查詢有沒有該Cookie User user = userService.findUserByLoginToken(loginToken); if (user != null) { request.getSession().setAttribute("user", user); return true; } else { //沒有該Cookie與之對應的用戶(Cookie不匹配) CookieUtil.clearCookie(request, response, "loginToken"); return false; } } else { //沒有cookie、也沒有登陸。是index請求獲取用戶信息,可以放行 if (request.getRequestURI().contains("session")) { return true; } //沒有cookie憑證 response.sendRedirect("/login.html"); return false; } } } }

總結一下上面代碼的思路:

用戶登錄時,驗證用戶的賬戶和密碼

生成一個Token保存在數據庫中,將Token寫到Cookie中

將用戶數據保存在Session中

請求時都會帶上Cookie,檢查有沒有登錄,如果已經登錄則放行

如果沒看懂的同學,建議回顧Session和Cookie和HTTP:

介紹會話技術、Cookie的API、詳解、應用

Session介紹、API、生命周期、應用、與Cookie區別

什么是HTTP

三、多系統登錄的問題與解決

3.1 Session不共享問題

單系統登錄功能主要是用Session保存用戶信息來實現的,但我們清楚的是:多系統即可能有多個Tomcat,而Session是依賴當前系統的Tomcat,所以系統A的Session和系統B的Session是不共享的。

解決系統之間Session不共享問題有一下幾種方案:

Tomcat集群Session全局復制(集群內每個tomcat的session完全同步)【會影響集群的性能呢,不建議】

根據請求的IP進行Hash映射到對應的機器上(這就相當于請求的IP一直會訪問同一個服務器)【如果服務器宕機了,會丟失了一大部分Session的數據,不建議】

把Session數據放在Redis中(使用Redis模擬Session)【建議

如果還不了解Redis的同學,建議移步(Redis合集)

我們可以將登錄功能多帶帶抽取出來,做成一個子系統。

SSO(登錄系統)的邏輯如下:

// 登錄功能(SSO多帶帶的服務)
@Override
public TaotaoResult login(String username, String password) throws Exception {
	
	//根據用戶名查詢用戶信息
	TbUserExample example = new TbUserExample();
	Criteria criteria = example.createCriteria();
	criteria.andUsernameEqualTo(username);
	List list = userMapper.selectByExample(example);
	if (null == list || list.isEmpty()) {
		return TaotaoResult.build(400, "用戶不存在");
	}
	//核對密碼
	TbUser user = list.get(0);
	if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
		return TaotaoResult.build(400, "密碼錯誤");
	}
	//登錄成功,把用戶信息寫入redis
	//生成一個用戶token
	String token = UUID.randomUUID().toString();
	jedisCluster.set(USER_TOKEN_KEY + ":" + token, JsonUtils.objectToJson(user));
	//設置session過期時間
	jedisCluster.expire(USER_TOKEN_KEY + ":" + token, SESSION_EXPIRE_TIME);
	return TaotaoResult.ok(token);
}

其他子系統登錄時,請求SSO(登錄系統)進行登錄,將返回的token寫到Cookie中,下次訪問時則把Cookie帶上:

public TaotaoResult login(String username, String password, 
		HttpServletRequest request, HttpServletResponse response) {
	//請求參數
	Map param = new HashMap<>();
	param.put("username", username);
	param.put("password", password);
	//登錄處理
	String stringResult = HttpClientUtil.doPost(REGISTER_USER_URL + USER_LOGIN_URL, param);
	TaotaoResult result = TaotaoResult.format(stringResult);
	//登錄出錯
	if (result.getStatus() != 200) {
		return result;
	}
	//登錄成功后把取token信息,并寫入cookie
	String token = (String) result.getData();
	//寫入cookie
	CookieUtils.setCookie(request, response, "TT_TOKEN", token);
	//返回成功
	return result;
	
}

總結:

SSO系統生成一個token,并將用戶信息存到Redis中,并設置過期時間

其他系統請求SSO系統進行登錄,得到SSO返回的token,寫到Cookie中

每次請求時,Cookie都會帶上,攔截器得到token,判斷是否已經登錄

到這里,其實我們會發現其實就兩個變化:

將登陸功能抽取為一個系統(SSO),其他系統請求SSO進行登錄

本來將用戶信息存到Session,現在將用戶信息存到Redis

3.2 Cookie跨域的問題

上面我們解決了Session不能共享的問題,但其實還有另一個問題。Cookie是不能跨域的

比如說,我們請求時,瀏覽器會自動把google.com的Cookie帶過去給google的服務器,而不會把的Cookie帶過去給google的服務器。

這就意味著,由于域名不同,用戶向系統A登錄后,系統A返回給瀏覽器的Cookie,用戶再請求系統B的時候不會將系統A的Cookie帶過去。

針對Cookie存在跨域問題,有幾種解決方案:

    服務端將Cookie寫到客戶端后,客戶端對Cookie進行解析,將Token解析出來,此后請求都把這個Token帶上就行了

    多個域名共享Cookie,在寫到客戶端的時候設置Cookie的domain。

    將Token保存在SessionStroage中(不依賴Cookie就沒有跨域的問題了)

到這里,我們已經可以實現單點登錄了。

3.3 CAS原理

說到單點登錄,就肯定會見到這個名詞:CAS (Central Authentication Service),下面說說CAS是怎么搞的。

如果已經將登錄多帶帶抽取成系統出來,我們還能這樣玩。現在我們有兩個系統,分別是www.java3y.comwww.java4y.com,一個SSOwww.sso.com

首先,用戶想要訪問系統Awww.java3y.com受限的資源(比如說購物車功能,購物車功能需要登錄后才能訪問),系統Awww.java3y.com發現用戶并沒有登錄,于是重定向到sso認證中心,并將自己的地址作為參數。請求的地址如下:

www.sso.com);

sso認證中心發現用戶未登錄,將用戶引導至登錄頁面,用戶進行輸入用戶名和密碼進行登錄,用戶與認證中心建立全局會話(生成一份Token,寫到Cookie中,保存在瀏覽器上)

隨后,認證中心重定向回系統A,并把Token攜帶過去給系統A,重定向的地址如下:

www.java3y.com);

接著,系統A去sso認證中心驗證這個Token是否正確,如果正確,則系統A和用戶建立局部會話(創建Session)。到此,系統A和用戶已經是登錄狀態了。

此時,用戶想要訪問系統Bwww.java4y.com受限的資源(比如說訂單功能,訂單功能需要登錄后才能訪問),系統Bwww.java4y.com發現用戶并沒有登錄,于是重定向到sso認證中心,并將自己的地址作為參數。請求的地址如下:

www.sso.com);

注意,因為之前用戶與認證中心www.sso.com已經建立了全局會話(當時已經把Cookie保存到瀏覽器上了),所以這次系統B重定向到認證中心www.sso.com是可以帶上Cookie的。

認證中心根據帶過來的Cookie發現已經與用戶建立了全局會話了,認證中心重定向回系統B,并把Token攜帶過去給系統B,重定向的地址如下:

www.java4y.com);

接著,系統B去sso認證中心驗證這個Token是否正確,如果正確,則系統B和用戶建立局部會話(創建Session)。到此,系統B和用戶已經是登錄狀態了。

看到這里,其實SSO認證中心就類似一個中轉站

參考資料:

www.cnblogs.com/EzrealLiu/p…

www.cnblogs.com/ywlaker/p/6…

blog.csdn.net/javaloveiph…

最后

樂于輸出干貨的Java技術公眾號:Java3y。公眾號內有200多篇原創技術文章、海量視頻資源、精美腦圖,關注即可獲取!

覺得我的文章寫得不錯,點

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7146.html

相關文章

  • 什么單點登錄(SSO)

    摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen… 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就一直躺在我的收藏夾里邊: ...

    番茄西紅柿 評論0 收藏0
  • 什么單點登錄(SSO)

    摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen… 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就一直躺在我的收藏夾里邊: ...

    2i18ns 評論0 收藏0
  • 什么單點登錄(SSO)

    摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。 前言 只有光頭才能變強。文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就...

    levy9527 評論0 收藏0
  • 系統的講解 - SSO單點登錄

    摘要:概念英文全稱,單點登錄。登錄如上述流程圖一致。系統和系統使用認證登錄。退出上圖,表示的是從某一個系統退出的流程圖。與的關系如果企業有多個管理系統,現由原來的每個系統都有一個登錄,調整為統一登錄認證。 概念 SSO 英文全稱 Single Sign On,單點登錄。 在多個應用系統中,只需要登錄一次,就可以訪問其他相互信任的應用系統。 比如:淘寶網(www.taobao.com),天貓網...

    Kylin_Mountain 評論0 收藏0
  • SSO單點登錄原理

    摘要:經紀人給被用于進一步請求的電子身份存取。基于網關基于,安全斷言標記語言的出現大大簡化了,并被批準為的執行標準。 什么是SSO? 單點登錄( Single Sign-On , 簡稱 SSO )是目前比較流行的服務于企業業務整合的解決方案之一 SSO 使得在多個應用系統中,用戶只需要 登錄一次 就可以訪問所有相互信任的應用系統 SSO 主要實現方式 共享 cookies 基于共享同域的...

    curried 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<