|
|
<?php
|
|
|
|
|
|
declare (strict_types=1);
|
|
|
|
|
|
namespace app\api\middleware;
|
|
|
|
|
|
use thans\jwt\exception\JWTException;
|
|
|
use thans\jwt\exception\TokenBlacklistException;
|
|
|
use thans\jwt\exception\TokenBlacklistGracePeriodException;
|
|
|
use thans\jwt\exception\TokenExpiredException;
|
|
|
use thans\jwt\middleware\JWTAuth;
|
|
|
use think\exception\HttpException;
|
|
|
|
|
|
/**
|
|
|
* JWT驗證刷新token機制
|
|
|
* Class JWTToken
|
|
|
* @package app\api\middleware
|
|
|
*/
|
|
|
class JWT extends JWTAuth
|
|
|
{
|
|
|
/**
|
|
|
* 刷新token
|
|
|
* @param $request
|
|
|
* @param \Closure $next
|
|
|
* @return mixed
|
|
|
* @throws JWTException
|
|
|
* @throws TokenBlacklistException
|
|
|
* @throws TokenBlacklistGracePeriodException
|
|
|
*/
|
|
|
public function handle($request, \Closure $next): object
|
|
|
{
|
|
|
try {
|
|
|
$payload = $this->auth->auth();
|
|
|
} catch (TokenExpiredException $e) { // token過期
|
|
|
// 嘗試刷新token,會將舊token加入黑名單
|
|
|
try {
|
|
|
$this->auth->setRefresh();
|
|
|
$token = $this->auth->refresh();
|
|
|
$payload = $this->auth->auth(false);
|
|
|
} catch (TokenBlacklistGracePeriodException $e) {
|
|
|
$payload = $this->auth->auth(false);
|
|
|
} catch (JWTException $exception) {
|
|
|
// 如果捕獲到此異常,即代表 refresh 也過期了,用户無法刷新令牌,需要重新登錄。
|
|
|
throw new HttpException(401, $exception->getMessage());
|
|
|
}
|
|
|
} catch (TokenBlacklistGracePeriodException $e) { // 捕獲黑名單寬限期
|
|
|
$payload = $this->auth->auth(false);
|
|
|
} catch (TokenBlacklistException $e) { // 捕獲黑名單,退出登錄或者已經自動刷新,當前token就會被拉黑
|
|
|
throw new HttpException(401, 'not login...');
|
|
|
}
|
|
|
|
|
|
$request->uid = $payload['user_id']->getValue();
|
|
|
|
|
|
$response = $next($request);
|
|
|
|
|
|
if (isset($token)) {
|
|
|
$this->setAuthentication($response, $token);
|
|
|
}
|
|
|
|
|
|
return $response;
|
|
|
}
|
|
|
} |