国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

解決使用jwt刷新token帶來的問題

whataa / 3471人閱讀

摘要:問題如何將新的發給前端比較好這個問題答案簡單,在的中設置。我這里使用解決的,將舊作為鍵,新作為值,設置一個秒過期的時間。大家可以享用這個新版,可以很好解決這個問題。

前后端分離,使用token的方式校驗用戶信息,我選擇了jwt,使用的教程在網上可以找到很多,不做介紹。

這里說明一個使用過程中,最重要的的一個環節刷新token帶來的問題。

業務要達到的目標:

用戶登錄一次之后,前端保存token,后面每次向后端請求的時候,header都帶上authorization信息,后端從請求中解析token,根據token驗證用戶信息,返回相應的信息。

相信大部分看過文檔并開始使用的同學都已經走通到這里了,下面是入坑的開始:

1. 產品要求

半個月內免登陸,這里就要使用到了refreshToken了,jwt設計思想很到位:設置發給前端的token一個有效期,比如2個小時,2個小時候前端發來的token就會失效,這個時候我們根據發來的token判斷下,如果這個token在2個小時外,并在刷新token的有效期內(比如半個月內),那么我們在給前端返回數據的時候返回一個新token,前端接到這個token存儲起來,當再次請求的時候,發送新的token,如此周而復始,只要你在半個月內沒有間斷去進入系統,那么完全不需要去進行登錄的操作。

2. 問題
1)如何將新的token發給前端比較好?

   這個問題答案簡單,在response 的header中設置authorization。
   關鍵點:后端一般使用的域名是二級域名比如我的是api.xx.com,會和前端產生一個跨域的影響,請記得一定要設置
   `$response->headers->set("Access-Control-Expose-Headers", "Authorization");`
   設置跨域的時候還要設置一個Cache-Control,這個東西出現的問題真的是莫名其妙,坑了我很久..
   `$response->headers->set("Cache-Control", "no-store"); // 無的話會導致前端從緩存獲取頭token`

2) 一般是在中間件中刷新token,當前請求繼續走,如何在controller中需要根據token調取登錄用戶信息?

   一下子可能沒說明問題,簡單理解為:token已經刷新了,那么當前token肯定失效了,繼續在controller利用請求中的token肯定會報token失效的錯誤,這里需要將新token帶到后面的程序處理中,我這里更改了當前請求頭,將newToken替換了request header中的Authorization。

3) 并發請求。也就是2個小時候之后,同一個頁面發來了2個請求,這個很正常,比如一個請求列表數據,一個請求搜索的表單,因為token都已失效,那么難道返回2個新的token回去?

   這個問題找了在github里面看到了issue但是無人回答,jwt肯定不會發兩個新的token回去的,那麼肯定會有一個token不僅是失效了,刷新當前token之后,產生新的token,舊token加入到了backlist中了,無法使用,那么另外一個請求自然無法成功。我這里使用Redis解決的,將舊token作為鍵,新token作為值,設置一個30秒過期的時間。當第二個請求來的時候,已經知道token在backlist中了,我們可以去redis查詢下是否存在這么個舊token,存在的話放行。

3. 關鍵中間件代碼

   setRequest($request)->getToken()) {
               return response()->json([
                   "code" => "2",
                   "msg" => "無參數token",
                   "data" => "",
               ]);
           }
   
           try {
               $user = $auth->authenticate($token);
               if (! $user) {
                   return response()->json([
                       "code" => "2",
                       "msg" => "未查詢到該用戶信息",
                       "data" => "",
                    ]);
               }
               $request->headers->set("Authorization","Bearer ".$token);
           } catch (TokenExpiredException $e) {
               try {
                   sleep(rand(1,5)/100);
                   $newToken = JWTAuth::refresh($token);
                   $request->headers->set("Authorization","Bearer ".$newToken); // 給當前的請求設置性的token,以備在本次請求中需要調用用戶信息
                   // 將舊token存儲在redis中,30秒內再次請求是有效的
                   Redis::setex("token_blacklist:".$token,30,$newToken);
               } catch (JWTException $e) {
                   // 在黑名單的有效期,放行
                   if($newToken = Redis::get("token_blacklist:".$token)){
                       $request->headers->set("Authorization","Bearer ".$newToken); // 給當前的請求設置性的token,以備在本次請求中需要調用用戶信息
                       return $next($request);
                   }
                   // 過期用戶
                   return response()->json([
                       "code" => "2",
                       "msg" => "賬號信息過期了,請重新登錄",
                   ]);
               }
           } catch (JWTException $e) {
               return response()->json([
                   "code" => "2",
                   "msg" => "無效token",
                   "data" => "",
                ]);
           }
           $response = $next($request);
   
           if ($newToken) {
               $response->headers->set("Authorization", "Bearer ".$newToken);
           }
   
           return $response;
       }
   }
   

一整天的時間耗在這里了,實踐才會發現問題,累并快樂著解決了^_^

=====================割了一了白了(2019)===================

關于第三個問題,當時寫的時候就感覺很惡心,作者已經出了一個新版本(1.0.0-rc.1),config里面多了一項配置
"blacklist_grace_period" => env("JWT_BLACKLIST_GRACE_PERIOD", 60)
當多個并發請求使用相同的JWT進行時,由于 access_token 的刷新 ,其中一些可能會失敗,以秒為單位設置請求時間以防止并發的請求失敗。
大家可以享用這個新版,可以很好解決這個問題。中間件更新了部分:

try {
    // 刷新token,超時刷新將會去catch
    $refresh = JWTAuth::parseToken()->refresh();
    $user = $auth->authenticate($refresh);
    // 生成新token(上面的$refresh也是合法的刷新token,這里如果直接用,2次刷新之后再無法繼續獲得,親測)
    $newToken = JWTAuth::fromUser($user);
    // 給當前的請求設置性的token,以備在本次請求中需要調用用戶信息
    $request->headers->set("Authorization","Bearer ".$newToken);
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28232.html

相關文章

  • 如何在SpringBoot中集成JWT(JSON Web Token)鑒權

    摘要:在使用非對稱加密算法進行簽名的時候,還可以用于驗證的發件人是否與中申明的發件人是同一個人。如果沒有用非對稱加密算法的話,把復制之后直接可以去官網在線解析。 這篇博客主要是簡單介紹了一下什么是JWT,以及如何在Spring Boot項目中使用JWT(JSON Web Token)。 1.關于JWT 1.1 什么是JWT 老生常談的開頭,我們要用這樣一種工具,首先得知道以下幾個問題。 這...

    yeyan1996 評論0 收藏0
  • JWT過期,修改密碼,注銷登錄如何處理

    摘要:設置過期時間每次登錄,包括登錄都返回一個可用的給客戶端,保證合理登錄的用戶都可以用,實現不會過期的效果。直接將中該用戶的信息過期。下次通過登錄,會提醒失效,要重新登錄,我們重新生成一個新的給用戶,然后。。通過存儲,實現過期失效的問題了。 JWT 使用場景:(自己總結的,每次請求攜帶token,然后到服務端驗證token是否正確,是否過期,然后解碼出攜帶的用戶信息。服務端不需要再存儲se...

    wdzgege 評論0 收藏0
  • 簽發用戶認證token超時刷新策略

    摘要:簽發的用戶認證超時刷新策略這個模塊分離至項目權限管理系統與前后端分離實踐,感覺那樣太長了找不到重點,分離出來要好點。這樣在有效期過后的時間段內可以申請刷新。 簽發的用戶認證token超時刷新策略 這個模塊分離至項目api權限管理系統與前后端分離實踐,感覺那樣太長了找不到重點,分離出來要好點。 對于登錄的用戶簽發其對應的jwt,我們在jwt設置他的固定有效期時間,在有效期內用戶攜帶jw...

    e10101 評論0 收藏0

發表評論

0條評論

whataa

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<