<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一、概述 認證的方式,主要有三種: 1、用戶名和密碼鑒權,使用Session保存用戶鑒權結果; 2、使用OAuth進行鑒權(其實OAuth也是一種基于Token的鑒權,只是沒有規定Token的生成方式)OAuth其實對于不做開放平臺的公司有些過于復雜; 3、自行采用Token進行鑒權; >[danger] 傳統的web應用,一般還是用傳統的session機制,而jwt適合于那些前后端分離的接口服務或restful api; ## 二、傳統的session認證 ### **概述** http協議本身是一種無狀態的協議,而這就意味著如果用戶向我們的應用提供了用戶名和密碼來進行用戶認證,那么下一次請求時,用戶還要再一次進行用戶認證才行,因為根據http協議,我們并不能知道是哪個用戶發出的請求,所以為了讓我們的應用能識別是哪個用戶發出的請求,我們只能在服務器存儲一份用戶登錄的信息,這份登錄信息會在響應時傳遞給瀏覽器,告訴其保存為cookie,以便下次請求時發送給我們的應用,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統的基于session認證。 ### **問題** **Session**: 每個用戶經過我們的應用認證之后,我們的應用都要在服務端做一次記錄,以方便用戶下次請求的鑒別,通常而言session都是保存在內存中,而隨著認證用戶的增多,服務端的開銷會明顯增大。 **擴展性**: 用戶認證之后,服務端做認證記錄,如果認證的記錄被保存在內存中的話,這意味著用戶下次請求還必須要請求在這臺服務器上,這樣才能拿到授權的資源,這樣在分布式的應用上,相應的限制了負載均衡器的能力。這也意味著限制了應用的擴展能力。 **CSRF**: 因為是基于cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。 ## 三、基于token的鑒權機制 ### **概述** 基于token的鑒權機制類似于http協議也是無狀態的,它不需要在服務端去保留用戶的認證信息或者會話信息。這就意味著基于token認證機制的應用不需要去考慮用戶在哪一臺服務器登錄了,這就為應用的擴展提供了便利。 這個token必須要在每次請求時傳遞給服務端,它應該保存在請求頭里, 另外,服務端要支持`CORS(跨來源資源共享)`策略,一般我們在服務端這么做就可以了`Access-Control-Allow-Origin: *` ### **流程** * 用戶使用用戶名密碼來請求服務器; * 服務器進行驗證用戶的信息; * 服務器通過驗證發送給用戶一個token; * 客戶端存儲token,并在每次請求時附送上這個token值; * 服務端驗證token值,并返回數據; ## 四、JWT JWT是由三段信息構成的,將這三段信息文本用`.`鏈接一起就構成了Jwt字符串。就像這樣: ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ ``` ### **JWT的構成** 三個部分構成,每個部分都是用BASE64編碼的,用`.`連接成一個完整的字符串,構成了最終的jwt; 第一部分我們稱它為頭部(header); jwt的頭部承載兩部分信息: * 聲明類型,這里是jwt * 聲明加密的算法 通常直接使用 HMAC SHA256 完整的頭部就像下面這樣的JSON: ``` { 'typ': 'JWT', 'alg': 'HS256' } 然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分頭部的內容了; eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 ``` 第二部分我們稱其為載荷(payload, 類似于飛機上承載的物品); 載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分: * 標準中注冊的聲明 * 公共的聲明 * 私有的聲明 **標準中注冊的聲明** (建議但不強制使用) : * **iss**: jwt簽發者 * **sub**: jwt所面向的用戶 * **aud**: 接收jwt的一方 * **exp**: jwt的過期時間,這個過期時間必須要大于簽發時間 * **nbf**: 定義在什么時間之前,該jwt都是不可用的. * **iat**: jwt的簽發時間 * **jti**: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。 **公共的聲明** : 公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密. **私有的聲明** : 私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。 定義一個payload: ``` { "sub": "1234567890", "name": "John Doe", "admin": true } 然后將其進行base64加密,得到Jwt的第二部分: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9 ``` 第三部分是簽證(signature); jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成: * header (base64后的) * payload (base64后的) * secret 這個部分需要base64加密后的header和base64加密后的payload使用`.`連接組成的字符串,然后通過header中聲明的加密方式進行加鹽`secret`組合加密,然后就構成了jwt的第三部分; >[danger] 注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了。 ### **交互過程** ![](https://img.kancloud.cn/50/b7/50b788cd6b9ec8c8e4ba1d13604f57ff_727x400.png) ### **總結** **優點:** * 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。 * 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。 * 便于傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便于傳輸的。 ### **安全相關** * 不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分。 * 保護好secret私鑰,該私鑰非常重要。 * 如果可以,請使用https協議 * 它不需要在服務端保存會話信息, 所以它易于應用的擴展
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看