<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>

                再來回顧下5.2節中請求數據時的header信息: ![](https://img.kancloud.cn/c6/ad/c6ad92a7720f4d71211ed4fd48a58d37_989x478.png) 此header中帶有很多項信息,比如:Accept的值為application/json,text/plain,*/*; Accept-Encoding的值為:gzip, deflate, br。我們把這種存儲方式稱為:鍵值對存儲。由于http協議傳輸的特性,在header中`鍵`與`值`的類型均為string(有人說也可以是number,其實這并不重要,重要的是明了只能傳字符串過來就行)。所以若要實現使用header傳遞令牌,首先要為令牌在header設置一個專業的`鍵`。此鍵的名稱可以隨意起,但一般習慣的命名為`auth-token 認證令牌`。 確認了令牌的鍵為`auth-token`后,按以下流程來分別完成開發: ![](https://img.kancloud.cn/ad/53/ad53edbbafc0cfca3c1bc7682204d450_334x188.png) ## 獲取header中的令牌 filter/TokenFilter.java ```java private String TOKEN_KEY = "auth-token"; ... @Override protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 獲取 header中的token String token = request.getHeader(this.TOKEN_KEY); ``` ## 有效性判斷 filter/TokenFilter.java ```java // 獲取 header中的token String token = request.getHeader(this.TOKEN_KEY); if (!this.validateToken(token)) { // 如果無效則分發送的token } ... } /** * 驗證token的有效性 * @param token token * @return */ private boolean validateToken(String token) { // 驗證token的有效性 } ``` 令牌是否有效,需要判斷其是否為系統分發的。傳入的令牌如果為系統分發,則有效;如系統未分發過該令牌,視為無效。因而,令牌有效性判斷的前提是系統存儲了分發過的令牌可以驗證用戶傳入的令牌是否存在于系統分發的令牌中。而java中的HashSet恰恰能夠解決當前問題: filter/TokenFilter.java ```java /** 存儲已分發過的令牌 */ private HashSet<String> tokens = new HashSet<>(); ``` 則驗證token是否有效的代碼如下: filter/TokenFilter.java ```java /** * 驗證token的有效性 * @param token token * @return */ private boolean validateToken(String token) { if (token == null) { return false; } return this.tokens.contains(token); } ``` ## 分發新token 發新token時主要注意要將生成的token存入歷史表中,再次接收到該token時以便進行校驗。 filter/TokenFilter.java ```java // 有效性判斷 if (!this.validateToken(token)) { // 如果無效則分發送的token token = this.makeToken(); } ... /** * 生成token * 將生成的token存入已分發的tokens中 * @return token */ private String makeToken() { String token = UUID.randomUUID().toString()?; this.tokens.add(token); return token; } ``` * ? 獲取非重復的隨機字符串 ## 測試 寫一點測試一點絕對是個好習慣。在代碼中加入一些日志語句,然后階段性的測試一下以驗證當前的代碼是符合預期的。 filter/TokenFilter.java ```java // 獲取 header中的token String token = request.getHeader(this.TOKEN_KEY); logger.info("獲取到的token為" + token); // 有效性判斷 if (!this.validateToken(token)) { // 如果無效則分發送的token token = this.makeToken(); logger.info("原token無效,發布的新的token為" + token); } ``` 重啟應用后,使用http request進行測試。 ### 測試一:未傳token ``` 2020-02-10 17:54:06.298 INFO 86327 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 獲取到的token為null 2020-02-10 17:54:06.298 INFO 86327 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 原token無效,發布的新的token為e953808a-015e-4b59-b348-6978f8d7c9cb ``` 未傳入token時分發新token符合預期。 ### 測試二:傳入有效的token 在測試文件中如下加入header信息。鍵為auth-token,值為剛剛控制臺打印的token。 ``` GET http://localhost:8080/Teacher auth-token: e953808a-015e-4b59-b348-6978f8d7c9cb ``` 發起請求: ``` 2020-02-10 17:57:26.775 INFO 86327 --- [nio-8080-exec-9] c.m.springbootstudy.filter.TokenFilter : 獲取到的token為e953808a-015e-4b59-b348-6978f8d7c9cb ``` 使用已分發的token進行請求,獲取了token并被驗證為有效。 ### 測試三:傳入無效的token 隨便的修正一下auth-token的值,再進行測試: ``` GET http://localhost:8080/Teacher auth-token: e953808a-015e-4b59-b348-12342321 ``` 測試結果: ``` 2020-02-10 17:58:51.978 INFO 86327 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 獲取到的token為e953808a-015e-4b59-b348-12342321 2020-02-10 17:58:51.978 INFO 86327 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 原token無效,發布的新的token為34d471c9-fc54-4ad6-8163-6a52a2ad2efe ``` # 生活中的令牌 生活中的令牌隨處可見: * 商鋪的會員卡就是一個令牌,每張會員卡都是一個令牌。會員卡在我們與商家家進行傳遞,商家根據會員卡來確認我們可以享有何種權益。 * 信用卡也是一個令牌,這個令牌更加智能。信用卡的密碼機制使該令牌擁有一種數據加密解密的能力;信用卡還擁有過期時間,只能在有效的時間內使用,這便是令牌的過期機制;同時當老的信用卡快過期時,發卡行還會為我們郵寄新卡,這便是令牌的過期更新機制。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step5.2.2](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step5.2.2) | - |
                  <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>

                              哎呀哎呀视频在线观看