摘要:此處做刷新處理具體代碼可以參考必須需要登錄驗(yàn)證的接口在響應(yīng)頭中返回新的問(wèn)題解決。
在做 API 開(kāi)發(fā)時(shí),不可避免會(huì)涉及到登錄驗(yàn)證,我使用的是jwt-auth
在登錄中會(huì)經(jīng)常遇到一個(gè)token過(guò)期的問(wèn)題,在config/jwt.php默認(rèn)設(shè)置中,這個(gè)過(guò)期時(shí)間是一個(gè)小時(shí),不過(guò)為了安全也可以設(shè)置更小一點(diǎn),我設(shè)置了為五分鐘。
五分鐘過(guò)期,如果就讓用戶(hù)去登錄,這種體驗(yàn)會(huì)讓用戶(hù)直接拋棄你的網(wǎng)站,所以這就會(huì)使用到刷新token這個(gè)功能
正常情況下是寫(xiě)一個(gè)刷新token的接口,當(dāng)過(guò)期的時(shí)候前端把過(guò)期的token帶上請(qǐng)求這個(gè)接口換取新的token
不過(guò)為了方便前端也可以使用后端刷新返回,直至不可刷新,我用的就是這個(gè)方法:使用 Jwt-Auth 實(shí)現(xiàn) API 用戶(hù)認(rèn)證以及無(wú)痛刷新訪問(wèn)令牌
而坑就是這樣來(lái)的,
在必須需要登錄驗(yàn)證的接口設(shè)置刷新token
checkForToken($request); try { /**************************************** * 嘗試通過(guò) tokne 登錄,如果正常,就獲取到用戶(hù) * 無(wú)法正確的登錄,拋出 token 異常 ****************************************/ if ($this->auth->parseToken()->authenticate()) { return $next($request); } throw new UnauthorizedHttpException("jwt-auth", "User not found"); } catch (TokenExpiredException $e) { try { /**************************************** * token 過(guò)期的異常,嘗試刷新 token * 使用 id 一次性登錄以保證此次請(qǐng)求的成功 ****************************************/ $token = $this->auth->refresh(); $id = $this->auth ->manager() ->getPayloadFactory() ->buildClaimsCollection() ->toPlainArray()["sub"]; auth()->onceUsingId($id); } catch (JWTException $e) { /**************************************** * 如果捕獲到此異常,即代表 refresh 也過(guò)期了, * 用戶(hù)無(wú)法刷新令牌,需要重新登錄。 ****************************************/ throw new UnauthorizedHttpException("jwt-auth", $e->getMessage(), null, StatusServe::HTTP_PAYMENT_REQUIRED); } } // 在響應(yīng)頭中返回新的 token return $this->setAuthenticationHeader($next($request), $token); } }
而有些頁(yè)面,比如文章列表頁(yè)面,這個(gè)接口登錄與不登錄皆可訪問(wèn),不過(guò)登錄的時(shí)候可以在頁(yè)面上顯示是否點(diǎn)贊了這篇文章。所以這個(gè)接口直接使用的是jwt-auth默認(rèn)的option中間件
* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace TymonJWTAuthHttpMiddleware; use Closure; use Exception; class Check extends BaseMiddleware { /** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure $next * * @return mixed */ public function handle($request, Closure $next) { if ($this->auth->parser()->setRequest($request)->hasToken()) { try { $this->auth->parseToken()->authenticate(); } catch (Exception $e) { } } return $next($request); } }
一開(kāi)始也沒(méi)有發(fā)現(xiàn)問(wèn)題,直到測(cè)試的時(shí)候,發(fā)現(xiàn)文章列表頁(yè)面點(diǎn)贊過(guò)的文章,過(guò)了一段時(shí)間再刷新的時(shí)候發(fā)現(xiàn)不顯示已點(diǎn)贊,但是進(jìn)入個(gè)人中心的已點(diǎn)贊文章可以看到。
剛開(kāi)始測(cè)試沒(méi)找出原因,直接暴力調(diào)試代碼,發(fā)現(xiàn)沒(méi)獲取到登錄用戶(hù),一想不對(duì)呀,已經(jīng)傳token為何獲取不到。經(jīng)過(guò)發(fā)現(xiàn),去到個(gè)人中心,再回到新聞列表頁(yè)就可以正常顯示,過(guò)了一段時(shí)間又不顯示了。
經(jīng)過(guò)這一輪之后,大概明白,在新聞列表頁(yè)時(shí),token已經(jīng)過(guò)期,但是當(dāng)時(shí)圖方便用的jwt-auth默認(rèn)的中間件,不會(huì)刷新token,所以這個(gè)接口獲取不到登錄的用戶(hù)。當(dāng)進(jìn)入個(gè)人中心,發(fā)現(xiàn)當(dāng)前token已經(jīng)過(guò)期,后臺(tái)刷新token返回,這時(shí)候再回到文章列表頁(yè)就可以得到正常的數(shù)據(jù),一段時(shí)間后,token又失效了,所以有無(wú)法看到點(diǎn)贊過(guò)的文章
解決方法,自己寫(xiě)一個(gè)option中間件,當(dāng)存在token的時(shí)候,也需要做token刷新處理。
auth->parser()->setRequest($request)->hasToken()) { try { $this->auth->parseToken()->authenticate(); } catch (TokenExpiredException $e) { // 此處做刷新 token 處理 // 具體代碼可以參考必須需要登錄驗(yàn)證的接口 // 在響應(yīng)頭中返回新的 token return $this->setAuthenticationHeader($next($request), $token); } catch (Exception $e) { } } return $next($request); } }
問(wèn)題解決。
最后說(shuō)一個(gè)并發(fā)會(huì)出現(xiàn)的問(wèn)題:
# 當(dāng)前 token_1 過(guò)期,先發(fā)起 a 請(qǐng)求,之后馬上發(fā)起 b 請(qǐng)求 # a 請(qǐng)求到服務(wù)器,服務(wù)器判斷過(guò)期,刷新 token_1 # 之后返回 token_2 給 a 請(qǐng)求響應(yīng) # 這時(shí)候遲一點(diǎn)的 b 請(qǐng)求用的還是 token_1 # 服務(wù)器已經(jīng)將此 token_1 加入黑名單,所以 b 請(qǐng)求無(wú)效 token_1 刷新返回 token_2 a 請(qǐng)求 --------> server -------> 成功 token_1 過(guò)期的 token_1,應(yīng)該使用 token_2 b 請(qǐng)求 --------> server ------> 失敗
jwt-auth已經(jīng)想到這種情況,我們只需要設(shè)置一個(gè)黑名單寬限時(shí)間即可
我設(shè)置為5秒,就是當(dāng)token_1過(guò)期了,你還能繼續(xù)使用token_1操作5秒時(shí)間
原文地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28900.html
摘要:目前正在寫(xiě)一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問(wèn)題和解決方法主要是前端。前端提交時(shí)使用,在后端再取出對(duì)應(yīng)的微信支付看了下文檔,以前是需要用喚起支付,而現(xiàn)在則是把微信內(nèi)置到了微信的瀏覽器中。 目前正在寫(xiě)一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問(wèn)題和解決方法(主要是前端)。內(nèi)容持續(xù)更新中~ 主要實(shí)現(xiàn) 前后端分離前端為 SPA 單頁(yè)面使用微信的JSSDK微信支付 技術(shù)方案 后端使用 php ...
摘要:目前正在寫(xiě)一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問(wèn)題和解決方法主要是前端。前端提交時(shí)使用,在后端再取出對(duì)應(yīng)的微信支付看了下文檔,以前是需要用喚起支付,而現(xiàn)在則是把微信內(nèi)置到了微信的瀏覽器中。 目前正在寫(xiě)一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問(wèn)題和解決方法(主要是前端)。內(nèi)容持續(xù)更新中~ 主要實(shí)現(xiàn) 前后端分離前端為 SPA 單頁(yè)面使用微信的JSSDK微信支付 技術(shù)方案 后端使用 php ...
摘要:備注登錄后可在開(kāi)發(fā)者中心查看對(duì)應(yīng)的接口權(quán)限。下載官網(wǎng)提供的示例代碼,參照中的代碼一步一步來(lái)實(shí)現(xiàn)。否則分享后的頁(yè)面會(huì)簽名失敗返回的與分享的是否一致 首先完成官方文檔前兩步(很好理解就不具體說(shuō)了):步驟一:綁定域名先登錄微信公眾平臺(tái)進(jìn)入公眾號(hào)設(shè)置的功能設(shè)置里填寫(xiě)JS接口安全域名。備注:登錄后可在開(kāi)發(fā)者中心查看對(duì)應(yīng)的接口權(quán)限。步驟二:引入JS文件在需要調(diào)用JS接口的頁(yè)面引入如下JS文件,(支...
摘要:這個(gè)坑就是要注意回調(diào)結(jié)束要返回成功的響應(yīng)這幾天做微信支付暫時(shí)遇到的問(wèn)題就這么多,只能說(shuō)注意細(xì)節(jié)吧,爬過(guò)的坑記錄下來(lái)以后遇到就懂處理了。 前言 其實(shí)任何接口開(kāi)發(fā)只要按照給出來(lái)的接口文檔和例子開(kāi)發(fā)基本上不會(huì)有太大問(wèn)題的,一些問(wèn)題都是出在雜七雜八的小細(xì)節(jié)上,現(xiàn)在分享一下微信支付開(kāi)發(fā)中自己遇到的小細(xì)節(jié)。按照文檔做完開(kāi)發(fā)前配置,比如JS安全域名配置、網(wǎng)頁(yè)授權(quán)域名、公眾號(hào)授權(quán)目錄等等... 坑一:...
摘要:今天看到了微信官方推出的一個(gè)瀏覽器插件,用來(lái)調(diào)試微信后臺(tái)和頁(yè)面的,挺好的。這個(gè)是根據(jù)別人的文章總結(jié)的,時(shí)間戳隨機(jī)數(shù)生成簽名將三者進(jìn)行加密與簽名進(jìn)行對(duì)比之后每次都會(huì)進(jìn)行身份校驗(yàn)。然而后面還有更深的坑。 原文摸索中遇到的一些坑,雖然很簡(jiǎn)單,但新手還是會(huì)被坑到,就稍微記錄一下吧,也當(dāng)學(xué)習(xí)手冊(cè),最好去了解一下express,不是很難,這邊只是簡(jiǎn)單的配置,更高級(jí)的接口還是去看文檔,模塊或者自己實(shí)...
閱讀 2774·2021-09-24 10:34
閱讀 1876·2021-09-22 10:02
閱讀 2265·2021-09-09 09:33
閱讀 1469·2021-08-13 15:02
閱讀 3279·2020-12-03 17:10
閱讀 1193·2019-08-30 15:44
閱讀 2156·2019-08-30 12:58
閱讀 3238·2019-08-26 13:40