硬核總結 9 個關于認證授權的常見問題!看看自己能回答幾個!
大家好,我是Guide哥!相信很多人對認證授權方面都不是特別了解,搞不清Session認證、JWT以及 Cookie 這些概念。所以,根據我根據日常對這部分學習已經在項目中的實際運用總結了這8 個相關的問題并且附上了詳細的回答(這篇文章這么晚才發的原因)。
所有問題如下,開始看答案之前不妨自己測驗一下自己究竟能回答幾個。
ps:部分問題其實我在之前寫JWT相關的文章的時候已經提到過了,看過的朋友看一下自己還記得不?
- 認證 (Authentication) 和授權 (Authorization)的區別是什么?
- 什么是Cookie ? Cookie的作用是什么?如何在服務端使用 Cookie ?
- Cookie 和 Session 有什么區別?如何使用Session進行身份驗證?
- 如果沒有Cookie的話Session還能用嗎?
- 為什么Cookie 無法防止CSRF攻擊,而token可以?
- 什么是 Token?什么是 JWT?如何基于Token進行身份驗證?
- 什么是OAuth 2.0?
- 什么是 SSO?
1. 認證 (Authentication) 和授權 (Authorization)的區別是什么?這是一個絕大多數人都會混淆的問題。
首先先從讀音上來認識這兩個名詞,很多人都會把它倆的讀音搞混,所以我建議你先先去查一查這兩個單詞到底該怎么讀,他們的具體含義是什么。
說簡單點就是:
認證 (Authentication): 你是誰。
授權 (Authorization): 你有權限干什么。
稍微正式點(啰嗦點)的說法就是:
- Authentication(認證) 是驗證您的身份的憑據(例如用戶名/用戶ID和密碼),通過這個憑據,系統得以知道你就是你,也就是說系統存在你這個用戶。所以,Authentication 被稱為身份/用戶驗證。
- Authorization(授權) 發生在 Authentication(認證) 之后。授權嘛,光看意思大家應該就明白,它主要掌管我們訪問系統的權限。比如有些特定資源只能具有特定權限的人才能訪問比如admin,有些對系統資源操作比如刪除、添加、更新只能特定人才具有。
這兩個一般在我們的系統中被結合在一起使用,目的就是為了保護我們系統的安全性。
2. 什么是Cookie ? Cookie的作用是什么?如何在服務端使用 Cookie ?
2.1 什么是Cookie ? Cookie的作用是什么?
Cookie 和 Session都是用來跟蹤瀏覽器用戶身份的會話方式,但是兩者的應用場景不太一樣。
維基百科是這樣定義 Cookie 的:Cookies是某些網站為了辨別用戶身份而儲存在用戶本地終端上的數據(通常經過加密)。簡單來說: Cookie 存放在客戶端,一般用來保存用戶信息。
下面是 Cookie 的一些應用案例:
- 我們在 Cookie 中保存已經登錄過的用戶信息,下次訪問網站的時候頁面可以自動幫你登錄的一些基本信息給填了。除此之外,Cookie 還能保存用戶首選項,主題和其他設置信息。
- 使用Cookie 保存 session 或者 token ,向后端發送請求的時候帶上 Cookie,這樣后端就能取到session或者token了。這樣就能記錄用戶當前的狀態了,因為 HTTP 協議是無狀態的。
- Cookie 還可以用來記錄和分析用戶行為。舉個簡單的例子你在網上購物的時候,因為HTTP協議是沒有狀態的,如果服務器想要獲取你在某個頁面的停留狀態或者看了哪些商品,一種常用的實現方式就是將這些信息存放在Cookie
2.2 如何在服務端使用 Cookie 呢?
這部分內容參考:https://attacomsian.com/blog/cookies-spring-boot,更多如何在Spring Boot中使用Cookie 的內容可以查看這篇文章。
1)設置cookie返回給客戶端
- @GetMapping("/change-username")
- public String setCookie(HttpServletResponse response) {
- // 創建一個 cookie
- Cookie cookie = new Cookie("username", "Jovan");
- //設置 cookie過期時間
- cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
- //添加到 response 中
- response.addCookie(cookie);
- return"Username is changed!";
- }
2) 使用Spring框架提供的@CookieValue注解獲取特定的 cookie的值
- @GetMapping("/")
- public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
- return"Hey! My username is " + username;
- }
3) 讀取所有的 Cookie 值
- @GetMapping("/all-cookies")
- public String readAllCookies(HttpServletRequest request) {
- Cookie[] cookies = request.getCookies();
- if (cookies != null) {
- return Arrays.stream(cookies)
- .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
- }
- return"No cookies";
- }
3. Cookie 和 Session 有什么區別?如何使用Session進行身份驗證?
Session 的主要作用就是通過服務端記錄用戶的狀態。 典型的場景是購物車,當你要添加商品到購物車的時候,系統不知道是哪個用戶操作的,因為 HTTP 協議是無狀態的。服務端給特定的用戶創建特定的 Session 之后就可以標識這個用戶并且跟蹤這個用戶了。
Cookie 數據保存在客戶端(瀏覽器端),Session 數據保存在服務器端。相對來說 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要寫入 Cookie 中,最好能將 Cookie 信息加密然后使用到的時候再去服務器端解密。
那么,如何使用Session進行身份驗證?
很多時候我們都是通過 SessionID 來實現特定的用戶,SessionID 一般會選擇存放在 Redis 中。舉個例子:用戶成功登陸系統,然后返回給客戶端具有 SessionID 的 Cookie,當用戶向后端發起請求的時候會把 SessionID 帶上,這樣后端就知道你的身份狀態了。關于這種認證方式更詳細的過程如下:
Session Based Authentication flow
- 用戶向服務器發送用戶名和密碼用于登陸系統。
- 服務器驗證通過后,服務器為用戶創建一個 Session,并將 Session信息存儲 起來。
- 服務器向用戶返回一個 SessionID,寫入用戶的 Cookie。
- 當用戶保持登錄狀態時,Cookie 將與每個后續請求一起被發送出去。
- 服務器可以將存儲在 Cookie 上的 Session ID 與存儲在內存中或者數據庫中的 Session 信息進行比較,以驗證用戶的身份,返回給用戶客戶端響應信息的時候會附帶用戶當前的狀態。
使用 Session 的時候需要注意下面幾個點:
- 依賴Session的關鍵業務一定要確保客戶端開啟了Cookie。
- 注意Session的過期時間
花了個圖簡單總結了一下Session認證涉及的一些東西。
另外,Spring Session提供了一種跨多個應用程序或實例管理用戶會話信息的機制。如果想詳細了解可以查看下面幾篇很不錯的文章:
- Getting Started with Spring Session
- Guide to Spring Session
- Sticky Sessions with Spring Session & Redis
4.如果沒有Cookie的話Session還能用嗎?這是一道經典的面試題!
一般是通過 Cookie 來保存 SessionID ,假如你使用了 Cookie 保存 SessionID的方案的話, 如果客戶端禁用了Cookie,那么Seesion就無法正常工作。
但是,并不是沒有 Cookie 之后就不能用 Session 了,比如你可以將SessionID放在請求的 url 里面https://javaguide.cn/?session_id=xxx 。這種方案的話可行,但是安全性和用戶體驗感降低。當然,為了你也可以對 SessionID 進行一次加密之后再傳入后端。
5.為什么Cookie 無法防止CSRF攻擊,而token可以?
CSRF(Cross Site Request Forgery)一般被翻譯為 跨站請求偽造 。那么什么是 跨站請求偽造 呢?說簡單用你的身份去發送一些對你不友好的請求。舉個簡單的例子:
小壯登錄了某網上銀行,他來到了網上銀行的帖子區,看到一個帖子下面有一個鏈接寫著“科學理財,年盈利率過萬”,小壯好奇的點開了這個鏈接,結果發現自己的賬戶少了10000元。這是這么回事呢?原來黑客在鏈接中藏了一個請求,這個請求直接利用小壯的身份給銀行發送了一個轉賬請求,也就是通過你的 Cookie 向銀行發出請求。
Token Based Authentication flow
用戶向服務器發送用戶名和密碼用于登陸系統。
身份驗證服務響應并返回了簽名的 JWT,上面包含了用戶是誰的內容。
用戶以后每次向后端發請求都在Header中帶上 JWT。
服務端檢查 JWT 并從中獲取用戶相關信息。
7 什么是OAuth 2.0?OAuth 是一個行業的標準授權協議,主要用來授權第三方應用獲取有限的權限。而 OAuth 2.0是對 OAuth 1.0 的完全重新設計,OAuth 2.0更快,更容易實現,OAuth 1.0 已經被廢棄。詳情請見:rfc6749。
實際上它就是一種授權機制,它的最終目的是為第三方應用頒發一個有時效性的令牌 token,使得第三方應用能夠通過該令牌獲取相關的資源。
OAuth 2.0 比較常用的場景就是第三方登錄,當你的網站接入了第三方登錄的時候一般就是使用的 OAuth 2.0 協議。
另外,現在OAuth 2.0也常見于支付場景(微信支付、支付寶支付)和開發平臺(微信開放平臺、阿里開放平臺等等)。
微信支付賬戶相關參數:
8 什么是 SSO?SSO(Single Sign On)即單點登錄說的是用戶登陸多個子系統的其中一個就有權訪問與其相關的其他系統。舉個例子我們在登陸了京東金融之后,我們同時也成功登陸京東的京東超市、京東家電等子系統。
9.SSO與OAuth2.0的區別OAuth 是一個行業的標準授權協議,主要用來授權第三方應用獲取有限的權限。SSO解決的是一個公司的多個相關的自系統的之間的登陸問題比如京東旗下相關子系統京東金融、京東超市、京東家電等等。
參考https://medium.com/@sherryhsu/session-vs-token-based-authentication-11a6c5ac45e4
https://www.varonis.com/blog/what-is-oauth/
https://tools.ietf.org/html/rfc6749