<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          13個認證授權(quán)常見面試題/知識點總結(jié)!(2021 最新版)

          共 9286字,需瀏覽 19分鐘

           ·

          2021-06-22 01:55

          大家好,我是 Guide哥!端午已過,又要開始工作學(xué)習(xí)啦!

          我發(fā)現(xiàn)有很多小伙伴對認證授權(quán)方面的知識不是特別了解,搞不清 Session 認證、JWT 以及 Cookie 這些概念。

          所以,根據(jù)我根據(jù)日常對這部分學(xué)習(xí)已經(jīng)在項目中的實際運用總結(jié)了這 13 個相關(guān)的問題并且附上了詳細的回答。希望能夠?qū)Υ蠹矣袔椭?span style="background-color: rgb(255, 255, 255);font-family: PingFangSC-Light;font-size: 16px;">

          認證 (Authentication) 和授權(quán) (Authorization)的區(qū)別是什么?

          這是一個絕大多數(shù)人都會混淆的問題。首先先從讀音上來認識這兩個名詞,很多人都會把它倆的讀音搞混,所以我建議你先先去查一查這兩個單詞到底該怎么讀,他們的具體含義是什么。

          說簡單點就是:

          • 認證 (Authentication): 你是誰。
          • 授權(quán) (Authorization): 你有權(quán)限干什么。

          稍微正式點(啰嗦點)的說法就是 :

          • Authentication(認證) 是驗證您的身份的憑據(jù)(例如用戶名/用戶 ID 和密碼),通過這個憑據(jù),系統(tǒng)得以知道你就是你,也就是說系統(tǒng)存在你這個用戶。所以,Authentication 被稱為身份/用戶驗證。
          • Authorization(授權(quán)) 發(fā)生在 Authentication(認證) 之后。授權(quán)嘛,光看意思大家應(yīng)該就明白,它主要掌管我們訪問系統(tǒng)的權(quán)限。比如有些特定資源只能具有特定權(quán)限的人才能訪問比如 admin,有些對系統(tǒng)資源操作比如刪除、添加、更新只能特定人才具有。

          認證

          授權(quán)

          這兩個一般在我們的系統(tǒng)中被結(jié)合在一起使用,目的就是為了保護我們系統(tǒng)的安全性。

          RBAC 模型了解嗎?

          系統(tǒng)權(quán)限控制最常采用的訪問控制模型就是 RBAC 模型

          什么是 RBAC 呢?

          RBAC 即基于角色的權(quán)限訪問控制(Role-Based Access Control)。這是一種通過角色關(guān)聯(lián)權(quán)限,角色同時又關(guān)聯(lián)用戶的授權(quán)的方式。

          簡單地說:一個用戶可以擁有若干角色,每一個角色有可以被分配若干權(quán)限這樣,就構(gòu)造成“用戶-角色-權(quán)限” 的授權(quán)模型。在這種模型中,用戶與角色、角色與權(quán)限之間構(gòu)成了多對多的關(guān)系,如下圖

          RBAC

          在 RBAC 中,權(quán)限與角色相關(guān)聯(lián),用戶通過成為適當(dāng)角色的成員而得到這些角色的權(quán)限。這就極大地簡化了權(quán)限的管理。

          通常 RBAC 下的權(quán)限設(shè)計相關(guān)的表有 5 張,其中有 2 張用于建立表之間的聯(lián)系:

          通過這個權(quán)限模型,我們可以創(chuàng)建不同的角色并為不同的角色分配不同的權(quán)限范圍(菜單)。

          通常來說,如果系統(tǒng)對于權(quán)限控制要求比較嚴(yán)格的話,一般都會選擇使用 RBAC 模型來做權(quán)限控制。

          什么是 Cookie ? Cookie 的作用是什么?

          CookieSession 都是用來跟蹤瀏覽器用戶身份的會話方式,但是兩者的應(yīng)用場景不太一樣。

          維基百科是這樣定義 Cookie 的:

          Cookies 是某些網(wǎng)站為了辨別用戶身份而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。

          簡單來說:Cookie 存放在客戶端,一般用來保存用戶信息

          下面是 Cookie 的一些應(yīng)用案例:

          1. 我們在 Cookie 中保存已經(jīng)登錄過的用戶信息,下次訪問網(wǎng)站的時候頁面可以自動幫你登錄的一些基本信息給填了。除此之外,Cookie 還能保存用戶首選項,主題和其他設(shè)置信息。
          2. 使用 Cookie 保存 Session 或者 Token ,向后端發(fā)送請求的時候帶上 Cookie,這樣后端就能取到 Session 或者 Token 了。這樣就能記錄用戶當(dāng)前的狀態(tài)了,因為 HTTP 協(xié)議是無狀態(tài)的。
          3. Cookie 還可以用來記錄和分析用戶行為。舉個簡單的例子你在網(wǎng)上購物的時候,因為 HTTP 協(xié)議是沒有狀態(tài)的,如果服務(wù)器想要獲取你在某個頁面的停留狀態(tài)或者看了哪些商品,一種常用的實現(xiàn)方式就是將這些信息存放在 Cookie
          4. ......

          如何在項目中使用 Cookie 呢?

          我這里以 Spring Boot 項目為例。

          1)設(shè)置 Cookie 返回給客戶端

          @GetMapping("/change-username")
          public String setCookie(HttpServletResponse response) {
              // 創(chuàng)建一個 cookie
              Cookie cookie = new Cookie("username""Jovan");
              //設(shè)置 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";
          }

          更多關(guān)于如何在 Spring Boot 中使用 Cookie 的內(nèi)容可以查看這篇文章:How to use cookies in Spring Boot[1]

          Cookie 和 Session 有什么區(qū)別?

          Session 的主要作用就是通過服務(wù)端記錄用戶的狀態(tài)。 典型的場景是購物車,當(dāng)你要添加商品到購物車的時候,系統(tǒng)不知道是哪個用戶操作的,因為 HTTP 協(xié)議是無狀態(tài)的。服務(wù)端給特定的用戶創(chuàng)建特定的 Session 之后就可以標(biāo)識這個用戶并且跟蹤這個用戶了。

          Cookie 數(shù)據(jù)保存在客戶端(瀏覽器端),Session 數(shù)據(jù)保存在服務(wù)器端。相對來說 Session 安全性更高。為了保證 Cookie中信息的安全性,最好能將 Cookie 信息加密然后使用到的時候再去服務(wù)器端解密。

          那么,如何使用 Session 進行身份驗證?

          如何使用 Session-Cookie 方案進行身份驗證?

          很多時候我們都是通過 SessionID 來實現(xiàn)特定的用戶,SessionID 一般會選擇存放在 Redis 中。舉個例子:

          1. 用戶成功登陸系統(tǒng),然后返回給客戶端具有 SessionIDCookie
          2. 當(dāng)用戶向后端發(fā)起請求的時候會把 SessionID 帶上,這樣后端就知道你的身份狀態(tài)了。

          關(guān)于這種認證方式更詳細的過程如下:

          1. 用戶向服務(wù)器發(fā)送用戶名、密碼、驗證碼用于登陸系統(tǒng)。
          2. 服務(wù)器驗證通過后,服務(wù)器為用戶創(chuàng)建一個 Session,并將 Session 信息存儲起來。
          3. 服務(wù)器向用戶返回一個 SessionID,寫入用戶的 Cookie
          4. 當(dāng)用戶保持登錄狀態(tài)時,Cookie 將與每個后續(xù)請求一起被發(fā)送出去。
          5. 服務(wù)器可以將存儲在 Cookie 上的 SessionID 與存儲在內(nèi)存中或者數(shù)據(jù)庫中的 Session 信息進行比較,以驗證用戶的身份,返回給用戶客戶端響應(yīng)信息的時候會附帶用戶當(dāng)前的狀態(tài)。

          使用 Session 的時候需要注意下面幾個點:

          1. 依賴 Session 的關(guān)鍵業(yè)務(wù)一定要確保客戶端開啟了 Cookie
          2. 注意 Session 的過期時間。

          另外,Spring Session 提供了一種跨多個應(yīng)用程序或?qū)嵗芾碛脩魰捫畔⒌臋C制。如果想詳細了解可以查看下面幾篇很不錯的文章:

          • Getting Started with Spring Session[2]
          • Guide to Spring Session[3]
          • Sticky Sessions with Spring Session & Redis[4]

          多服務(wù)器節(jié)點下 Session-Cookie 方案如何做?

          Session-Cookie 方案在單體環(huán)境是一個非常好的身份認證方案。但是,當(dāng)服務(wù)器水平拓展成多節(jié)點時,Session-Cookie 方案就要面臨挑戰(zhàn)了。

          舉個例子:假如我們部署了兩份相同的服務(wù) A,B,用戶第一次登陸的時候 ,Nginx 通過負載均衡機制將用戶請求轉(zhuǎn)發(fā)到 A 服務(wù)器,此時用戶的 Session 信息保存在 A 服務(wù)器。結(jié)果,用戶第二次訪問的時候 Nginx 將請求路由到 B 服務(wù)器,由于 B 服務(wù)器沒有保存 用戶的 Session 信息,導(dǎo)致用戶需要重新進行登陸。

          我們應(yīng)該如何避免上面這種情況的出現(xiàn)呢?

          有幾個方案可供大家參考:

          1. 某個用戶的所有請求都通過特性的哈希策略分配給同一個服務(wù)器處理。這樣的話,每個服務(wù)器都保存了一部分用戶的 Session 信息。服務(wù)器宕機,其保存的所有 Session 信息就完全丟失了。
          2. 每一個服務(wù)器保存的 Session 信息都是互相同步的,也就是說每一個服務(wù)器都保存了全量的 Session 信息。每當(dāng)一個服務(wù)器的 Session 信息發(fā)生變化,我們就將其同步到其他服務(wù)器。這種方案成本太大,并且,節(jié)點越多時,同步成本也越高。
          3. 單獨使用一個所有服務(wù)器都能訪問到的數(shù)據(jù)節(jié)點(比如緩存)來存放 Session 信息。為了保證高可用,數(shù)據(jù)節(jié)點盡量要避免是單點。

          如果沒有 Cookie 的話 Session 還能用嗎?

          這是一道經(jīng)典的面試題!

          一般是通過 Cookie 來保存 SessionID ,假如你使用了 Cookie 保存 SessionID 的方案的話, 如果客戶端禁用了 Cookie,那么 Session 就無法正常工作。

          但是,并不是沒有 Cookie 之后就不能用 Session 了,比如你可以將 SessionID 放在請求的 url 里面https://javaguide.cn/?Session_id=xxx 。這種方案的話可行,但是安全性和用戶體驗感降低。當(dāng)然,為了你也可以對 SessionID 進行一次加密之后再傳入后端。

          為什么 Cookie 無法防止 CSRF 攻擊,而 Token 可以?

          CSRF(Cross Site Request Forgery)一般被翻譯為 跨站請求偽造 。那么什么是 跨站請求偽造 呢?說簡單用你的身份去發(fā)送一些對你不友好的請求。舉個簡單的例子:

          小壯登錄了某網(wǎng)上銀行,他來到了網(wǎng)上銀行的帖子區(qū),看到一個帖子下面有一個鏈接寫著“科學(xué)理財,年盈利率過萬”,小壯好奇的點開了這個鏈接,結(jié)果發(fā)現(xiàn)自己的賬戶少了 10000 元。這是這么回事呢?原來黑客在鏈接中藏了一個請求,這個請求直接利用小壯的身份給銀行發(fā)送了一個轉(zhuǎn)賬請求,也就是通過你的 Cookie 向銀行發(fā)出請求。

          <a src=http://www.mybank.com/Transfer?bankId=11&money=10000>科學(xué)理財,年盈利率過萬</>

          上面也提到過,進行 Session 認證的時候,我們一般使用 Cookie 來存儲 SessionId,當(dāng)我們登陸后后端生成一個 SessionId 放在 Cookie 中返回給客戶端,服務(wù)端通過 Redis 或者其他存儲工具記錄保存著這個 SessionId,客戶端登錄以后每次請求都會帶上這個 SessionId,服務(wù)端通過這個 SessionId 來標(biāo)示你這個人。如果別人通過 Cookie 拿到了 SessionId 后就可以代替你的身份訪問系統(tǒng)了。

          Session 認證中 Cookie 中的 SessionId 是由瀏覽器發(fā)送到服務(wù)端的,借助這個特性,攻擊者就可以通過讓用戶誤點攻擊鏈接,達到攻擊效果。

          但是,我們使用 Token 的話就不會存在這個問題,在我們登錄成功獲得 Token 之后,一般會選擇存放在 localStorage (瀏覽器本地存儲)中。然后我們在前端通過某些方式會給每個發(fā)到后端的請求加上這個 Token,這樣就不會出現(xiàn) CSRF 漏洞的問題。因為,即使有個你點擊了非法鏈接發(fā)送了請求到服務(wù)端,這個非法請求是不會攜帶 Token 的,所以這個請求將是非法的。

          需要注意的是不論是 Cookie 還是 Token 都無法避免 跨站腳本攻擊(Cross Site Scripting)XSS

          跨站腳本攻擊(Cross Site Scripting)縮寫為 CSS 但這會與層疊樣式表(Cascading Style Sheets,CSS)的縮寫混淆。因此,有人將跨站腳本攻擊縮寫為 XSS。

          XSS 中攻擊者會用各種方式將惡意代碼注入到其他用戶的頁面中。就可以通過腳本盜用信息比如 Cookie

          推薦閱讀:如何防止 CSRF 攻擊?—美團技術(shù)團隊[5]

          什么是 Token?什么是 JWT?

          我們在前面的問題中探討了使用 Session 來鑒別用戶的身份,并且給出了幾個 Spring Session 的案例分享。我們知道 Session 信息需要保存一份在服務(wù)器端。這種方式會帶來一些麻煩,比如需要我們保證保存 Session 信息服務(wù)器的可用性、不適合移動端(依賴 Cookie)等等。

          有沒有一種不需要自己存放 Session 信息就能實現(xiàn)身份驗證的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是這種方式的實現(xiàn),通過這種方式服務(wù)器端就不需要保存 Session 數(shù)據(jù)了,只用在客戶端保存服務(wù)端返回給客戶的 Token 就可以了,擴展性得到提升。

          JWT 本質(zhì)上就一段簽名的 JSON 格式的數(shù)據(jù)。由于它是帶有簽名的,因此接收者便可以驗證它的真實性。

          下面是 RFC 7519[6] 對 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)[7]

          JWT 由 3 部分構(gòu)成:

          1. Header : 描述 JWT 的元數(shù)據(jù),定義了生成簽名的算法以及 Token 的類型。
          2. Payload : 用來存放實際需要傳遞的數(shù)據(jù)
          3. Signature(簽名) :服務(wù)器通過PayloadHeader和一個密鑰(secret)使用 Header 里面指定的簽名算法(默認是 HMAC SHA256)生成。

          如何基于 Token 進行身份驗證?

          在基于 Token 進行身份驗證的的應(yīng)用程序中,服務(wù)器通過PayloadHeader和一個密鑰(secret)創(chuàng)建令牌(Token)并將 Token 發(fā)送給客戶端,客戶端將 Token 保存在 Cookie 或者 localStorage 里面,以后客戶端發(fā)出的所有請求都會攜帶這個令牌。你可以把它放在 Cookie 里面自動發(fā)送,但是這樣不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization 字段中:Authorization: Bearer Token

          jwt
          1. 用戶向服務(wù)器發(fā)送用戶名和密碼用于登陸系統(tǒng)。
          2. 身份驗證服務(wù)響應(yīng)并返回了簽名的 JWT,上面包含了用戶是誰的內(nèi)容。
          3. 用戶以后每次向后端發(fā)請求都在 Header 中帶上 JWT。
          4. 服務(wù)端檢查 JWT 并從中獲取用戶相關(guān)信息。

          什么是 SSO?

          SSO(Single Sign On)即單點登錄說的是用戶登陸多個子系統(tǒng)的其中一個就有權(quán)訪問與其相關(guān)的其他系統(tǒng)。舉個例子我們在登陸了京東金融之后,我們同時也成功登陸京東的京東超市、京東國際、京東生鮮等子系統(tǒng)。

          sso

          什么是 OAuth 2.0?

          OAuth 是一個行業(yè)的標(biāo)準(zhǔn)授權(quán)協(xié)議,主要用來授權(quán)第三方應(yīng)用獲取有限的權(quán)限。而 OAuth 2.0 是對 OAuth 1.0 的完全重新設(shè)計,OAuth 2.0 更快,更容易實現(xiàn),OAuth 1.0 已經(jīng)被廢棄。詳情請見:rfc6749[8]

          實際上它就是一種授權(quán)機制,它的最終目的是為第三方應(yīng)用頒發(fā)一個有時效性的令牌 Token,使得第三方應(yīng)用能夠通過該令牌獲取相關(guān)的資源。

          OAuth 2.0 比較常用的場景就是第三方登錄,當(dāng)你的網(wǎng)站接入了第三方登錄的時候一般就是使用的 OAuth 2.0 協(xié)議。

          另外,現(xiàn)在 OAuth 2.0 也常見于支付場景(微信支付、支付寶支付)和開發(fā)平臺(微信開放平臺、阿里開放平臺等等)。


          下圖是 Slack OAuth 2.0 第三方登錄[9]的示意圖:

          推薦閱讀:

          • OAuth 2.0 的一個簡單解釋[10]
          • 10 分鐘理解什么是 OAuth 2.0 協(xié)議[11]
          • OAuth 2.0 的四種方式[12]
          • GitHub OAuth 第三方登錄示例教程[13]

          參考資料

          [1]

          How to use cookies in Spring Boot: https://attacomsian.com/blog/cookies-spring-boot。

          [2]

          Getting Started with Spring Session: https://codeboje.de/spring-Session-tutorial/

          [3]

          Guide to Spring Session: https://www.baeldung.com/spring-Session

          [4]

          Sticky Sessions with Spring Session & Redis: https://medium.com/@gvnix/sticky-Sessions-with-spring-Session-redis-bdc6f7438cc3

          [5]

          如何防止 CSRF 攻擊?—美團技術(shù)團隊: https://tech.meituan.com/2018/10/11/fe-security-csrf.html

          [6]

          RFC 7519: https://tools.ietf.org/html/rfc7519

          [7]

          JSON Web Token (JWT): https://tools.ietf.org/html/rfc7519

          [8]

          rfc6749: https://tools.ietf.org/html/rfc6749

          [9]

          Slack OAuth 2.0 第三方登錄: https://api.slack.com/legacy/oauth

          [10]

          OAuth 2.0 的一個簡單解釋: http://www.ruanyifeng.com/blog/2019/04/oauth_design.html

          [11]

          10 分鐘理解什么是 OAuth 2.0 協(xié)議: https://deepzz.com/post/what-is-oauth2-protocol.html

          [12]

          OAuth 2.0 的四種方式: http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

          [13]

          GitHub OAuth 第三方登錄示例教程: http://www.ruanyifeng.com/blog/2019/04/github-oauth.html


          < END >


          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中国无套毛片学生妹女 | 日本内射在线观看 | 黄色网亚洲| 网址在线| 中文字幕第18页 |