一问带你区分清楚Authentication,Authorization以及Cookie、Session、Token
很多人可能對(duì)權(quán)限認(rèn)證領(lǐng)域一些常見的概念都不是特別了解,所以寫了篇文章專門介紹一下這些概念。
1. 認(rèn)證 (Authentication) 和授權(quán) (Authorization)的區(qū)別是什么?
這是一個(gè)絕大多數(shù)人都會(huì)混淆的問題。首先先從讀音上來認(rèn)識(shí)這兩個(gè)名詞,很多人都會(huì)把它倆的讀音搞混,所以我建議你先先去查一查這兩個(gè)單詞到底該怎么讀,他們的具體含義是什么。
說簡(jiǎn)單點(diǎn)就是:
認(rèn)證 (Authentication):?你是誰。
授權(quán) (Authorization):?你有權(quán)限干什么。
稍微正式點(diǎn)(啰嗦點(diǎn))的說法就是:
Authentication(認(rèn)證)?是驗(yàn)證您的身份的憑據(jù)(例如用戶名/用戶ID和密碼),通過這個(gè)憑據(jù),系統(tǒng)得以知道你就是你,也就是說系統(tǒng)存在你這個(gè)用戶。所以,Authentication 被稱為身份/用戶驗(yàn)證。
Authorization(授權(quán))?發(fā)生在?Authentication(認(rèn)證)之后。授權(quán)嘛,光看意思大家應(yīng)該就明白,它主要掌管我們?cè)L問系統(tǒng)的權(quán)限。比如有些特定資源只能具有特定權(quán)限的人才能訪問比如admin,有些對(duì)系統(tǒng)資源操作比如刪除、添加、更新只能特定人才具有。
這兩個(gè)一般在我們的系統(tǒng)中被結(jié)合在一起使用,目的就是為了保護(hù)我們系統(tǒng)的安全性。
2. 什么是Cookie ? Cookie的作用是什么?如何在服務(wù)端使用 Cookie ?
2.1 什么是Cookie ? Cookie的作用是什么?
Cookie 和 Session都是用來跟蹤瀏覽器用戶身份的會(huì)話方式,但是兩者的應(yīng)用場(chǎng)景不太一樣。
維基百科是這樣定義 Cookie 的:Cookies是某些網(wǎng)站為了辨別用戶身份而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。簡(jiǎn)單來說:?Cookie 存放在客戶端,一般用來保存用戶信息。
下面是 Cookie 的一些應(yīng)用案例:
我們?cè)?Cookie 中保存已經(jīng)登錄過的用戶信息,下次訪問網(wǎng)站的時(shí)候頁面可以自動(dòng)幫你登錄的一些基本信息給填了。除此之外,Cookie 還能保存用戶首選項(xiàng),主題和其他設(shè)置信息。
使用Cookie 保存 session 或者 token ,向后端發(fā)送請(qǐng)求的時(shí)候帶上 Cookie,這樣后端就能取到session或者token了。這樣就能記錄用戶當(dāng)前的狀態(tài)了,因?yàn)?HTTP 協(xié)議是無狀態(tài)的。
Cookie 還可以用來記錄和分析用戶行為。舉個(gè)簡(jiǎn)單的例子你在網(wǎng)上購(gòu)物的時(shí)候,因?yàn)镠TTP協(xié)議是沒有狀態(tài)的,如果服務(wù)器想要獲取你在某個(gè)頁面的停留狀態(tài)或者看了哪些商品,一種常用的實(shí)現(xiàn)方式就是將這些信息存放在Cookie
2.2 如何能在 服務(wù)端使用 Cookie 呢?
這部分內(nèi)容參考:https://attacomsian.com/blog/cookies-spring-boot,更多如何在Spring Boot中使用Cookie 的內(nèi)容可以查看這篇文章。
1)設(shè)置cookie返回給客戶端
1@GetMapping("/change-username")2public?String?setCookie(HttpServletResponse?response)?{3????//?創(chuàng)建一個(gè)?cookie4????Cookie?cookie?=?new?Cookie("username",?"Jovan");5????//設(shè)置?cookie過期時(shí)間6????cookie.setMaxAge(7?*?24?*?60?*?60);?//?expires?in?7?days7????//添加到?response?中8????response.addCookie(cookie);9 10????return?"Username?is?changed!"; 11}2) 使用Spring框架提供的@CookieValue注解獲取特定的 cookie的值
1@GetMapping("/") 2public?String?readCookie(@CookieValue(value?=?"username",?defaultValue?=?"Atta")?String?username)?{ 3????return?"Hey!?My?username?is?"?+?username; 4}3) 讀取所有的 Cookie 值
1@GetMapping("/all-cookies")2public?String?readAllCookies(HttpServletRequest?request)?{34????Cookie[]?cookies?=?request.getCookies();5????if?(cookies?!=?null)?{6????????return?Arrays.stream(cookies)7????????????????.map(c?->?c.getName()?+?"="?+?c.getValue()).collect(Collectors.joining(",?"));8????}9 10????return?"No?cookies"; 11}3. Cookie 和 Session 有什么區(qū)別?如何使用Session進(jìn)行身份驗(yàn)證?
Session 的主要作用就是通過服務(wù)端記錄用戶的狀態(tài)。?典型的場(chǎng)景是購(gòu)物車,當(dāng)你要添加商品到購(gòu)物車的時(shí)候,系統(tǒng)不知道是哪個(gè)用戶操作的,因?yàn)?HTTP 協(xié)議是無狀態(tài)的。服務(wù)端給特定的用戶創(chuàng)建特定的 Session 之后就可以標(biāo)識(shí)這個(gè)用戶并且跟蹤這個(gè)用戶了。
Cookie 數(shù)據(jù)保存在客戶端(瀏覽器端),Session 數(shù)據(jù)保存在服務(wù)器端。相對(duì)來說 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要寫入 Cookie 中,最好能將 Cookie 信息加密然后使用到的時(shí)候再去服務(wù)器端解密。
那么,如何使用Session進(jìn)行身份驗(yàn)證?
很多時(shí)候我們都是通過 SessionID 來實(shí)現(xiàn)特定的用戶,SessionID 一般會(huì)選擇存放在 Redis 中。舉個(gè)例子:用戶成功登陸系統(tǒng),然后返回給客戶端具有 SessionID 的 Cookie,當(dāng)用戶向后端發(fā)起請(qǐng)求的時(shí)候會(huì)把 SessionID 帶上,這樣后端就知道你的身份狀態(tài)了。關(guān)于這種認(rèn)證方式更詳細(xì)的過程如下:
Session Based Authentication flow用戶向服務(wù)器發(fā)送用戶名和密碼用于登陸系統(tǒng)。
服務(wù)器驗(yàn)證通過后,服務(wù)器為用戶創(chuàng)建一個(gè) Session,并將 Session信息存儲(chǔ) 起來。
服務(wù)器向用戶返回一個(gè) SessionID,寫入用戶的 Cookie。
當(dāng)用戶保持登錄狀態(tài)時(shí),Cookie 將與每個(gè)后續(xù)請(qǐng)求一起被發(fā)送出去。
服務(wù)器可以將存儲(chǔ)在 Cookie 上的 Session ID 與存儲(chǔ)在內(nèi)存中或者數(shù)據(jù)庫中的 Session 信息進(jìn)行比較,以驗(yàn)證用戶的身份,返回給用戶客戶端響應(yīng)信息的時(shí)候會(huì)附帶用戶當(dāng)前的狀態(tài)。
另外,Spring Session提供了一種跨多個(gè)應(yīng)用程序或?qū)嵗芾碛脩魰?huì)話信息的機(jī)制。如果想詳細(xì)了解可以查看下面幾篇很不錯(cuò)的文章:
Getting Started with Spring Session
Guide to Spring Session
Sticky Sessions with Spring Session & Redis
4. 什么是 Token?什么是 JWT?如何基于Token進(jìn)行身份驗(yàn)證?
我們?cè)谏弦粋€(gè)問題中探討了使用 Session 來鑒別用戶的身份,并且給出了幾個(gè) Spring Session 的案例分享。我們知道 Session 信息需要保存一份在服務(wù)器端。這種方式會(huì)帶來一些麻煩,比如需要我們保證保存 Session 信息服務(wù)器的可用性、不適合移動(dòng)端(依賴Cookie)等等。
有沒有一種不需要自己存放 Session 信息就能實(shí)現(xiàn)身份驗(yàn)證的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是這種方式的實(shí)現(xiàn),通過這種方式服務(wù)器端就不需要保存 Session 數(shù)據(jù)了,只用在客戶端保存服務(wù)端返回給客戶的 Token 就可以了,擴(kuò)展性得到提升。
JWT 本質(zhì)上就一段簽名的 JSON 格式的數(shù)據(jù)。由于它是帶有簽名的,因此接收者便可以驗(yàn)證它的真實(shí)性。
下面是 RFC 7519 對(duì) JWT 做的較為正式的定義。
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. ——JSON Web Token (JWT)
JWT 由 3 部分構(gòu)成:
Header :描述 JWT 的元數(shù)據(jù)。定義了生成簽名的算法以及 Token 的類型。
Payload(負(fù)載):用來存放實(shí)際需要傳遞的數(shù)據(jù)
Signature(簽名):服務(wù)器通過Payload、Header和一個(gè)密鑰(secret)使用 Header 里面指定的簽名算法(默認(rèn)是 HMAC SHA256)生成。
在基于 Token 進(jìn)行身份驗(yàn)證的的應(yīng)用程序中,服務(wù)器通過Payload、Header和一個(gè)密鑰(secret)創(chuàng)建令牌(Token)并將?Token?發(fā)送給客戶端,客戶端將?Token?保存在 Cookie 或者 localStorage 里面,以后客戶端發(fā)出的所有請(qǐng)求都會(huì)攜帶這個(gè)令牌。你可以把它放在 Cookie 里面自動(dòng)發(fā)送,但是這樣不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization字段中:Authorization: Bearer Token。
Token Based Authentication flow用戶向服務(wù)器發(fā)送用戶名和密碼用于登陸系統(tǒng)。
身份驗(yàn)證服務(wù)響應(yīng)并返回了簽名的 JWT,上面包含了用戶是誰的內(nèi)容。
用戶以后每次向后端發(fā)請(qǐng)求都在Header中帶上 JWT。
服務(wù)端檢查 JWT 并從中獲取用戶相關(guān)信息。
5 什么是OAuth 2.0?
OAuth 是一個(gè)行業(yè)的標(biāo)準(zhǔn)授權(quán)協(xié)議,主要用來授權(quán)第三方應(yīng)用獲取有限的權(quán)限。而 OAuth 2.0是對(duì) OAuth 1.0 的完全重新設(shè)計(jì),OAuth 2.0更快,更容易實(shí)現(xiàn),OAuth 1.0 已經(jīng)被廢棄。詳情請(qǐng)見:rfc6749。
實(shí)際上它就是一種授權(quán)機(jī)制,它的最終目的是為第三方應(yīng)用頒發(fā)一個(gè)有時(shí)效性的令牌 token,使得第三方應(yīng)用能夠通過該令牌獲取相關(guān)的資源。
OAuth 2.0 比較常用的場(chǎng)景就是第三方登錄,當(dāng)你的網(wǎng)站接入了第三方登錄的時(shí)候一般就是使用的 OAuth 2.0 協(xié)議。
參考
https://medium.com/@sherryhsu/session-vs-token-based-authentication-11a6c5ac45e4
https://www.varonis.com/blog/what-is-oauth/
https://tools.ietf.org/html/rfc6749
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號(hào)
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的一问带你区分清楚Authentication,Authorization以及Cookie、Session、Token的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 14 会场安排问题
- 下一篇: 交替字符串