|
|
<?php
|
|
|
|
|
|
declare (strict_types=1);
|
|
|
|
|
|
namespace app\appapi\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 Firebase\JWT\JWT as FireJWT;
|
|
|
use Firebase\JWT\Key as FireKey;
|
|
|
use Firebase\JWT\SignatureInvalidException;
|
|
|
use Firebase\JWT\BeforeValidException;
|
|
|
use Firebase\JWT\ExpiredException;
|
|
|
|
|
|
use think\exception\HttpException;
|
|
|
use think\facade\Log;
|
|
|
|
|
|
/**
|
|
|
* JWT驗證刷新token機制
|
|
|
* Class JWTToken
|
|
|
* @package app\api\middleware
|
|
|
*/
|
|
|
class JWT
|
|
|
{
|
|
|
/**
|
|
|
* 刷新token
|
|
|
* @param $request
|
|
|
* @param \Closure $next
|
|
|
* @return mixed
|
|
|
* @throws JWTException
|
|
|
* @throws TokenBlacklistException
|
|
|
* @throws TokenBlacklistGracePeriodException
|
|
|
*/
|
|
|
public function handle($request, \Closure $next): object
|
|
|
{
|
|
|
|
|
|
if ($request->isOptions()) {
|
|
|
return response();
|
|
|
}
|
|
|
|
|
|
// try{
|
|
|
try{
|
|
|
$payload = FireJWT::decode(trim(str_replace('Bearer ','',$request->header('authorization'))), new FireKey(\think\facade\Config::get('jwt.secret'), 'HS256'));
|
|
|
$decoded = (array) $payload;
|
|
|
// } catch (SignatureInvalidException $e) {
|
|
|
// throw new HttpException(401, 'token error...');
|
|
|
// } catch (BeforeValidException $e) {
|
|
|
// // provided JWT is trying to be used before "nbf" claim OR
|
|
|
// // provided JWT is trying to be used before "iat" claim.
|
|
|
// } catch (ExpiredException $e) {
|
|
|
// print_r($e);
|
|
|
// // token過期
|
|
|
// throw new HttpException(401, 'login error...');
|
|
|
} catch(\Exception $e){
|
|
|
throw new HttpException(401, $e->getMessage());
|
|
|
}
|
|
|
|
|
|
// 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(\Exception $e){
|
|
|
// throw new HttpException(401, $e->getMessage());
|
|
|
// }
|
|
|
// } catch (TokenBlacklistGracePeriodException $e) { // 捕獲黑名單寬限期
|
|
|
// $payload = $this->auth->auth(false);
|
|
|
// } catch (TokenBlacklistException $e) { // 捕獲黑名單,退出登錄或者已經自動刷新,當前token就會被拉黑
|
|
|
// throw new HttpException(401, 'not login...');
|
|
|
// }catch (\Exception $e){
|
|
|
// throw new HttpException(401, 'login error...');
|
|
|
// }
|
|
|
|
|
|
if(isset($payload)){
|
|
|
$request->uid = $payload->user_id;
|
|
|
}else{
|
|
|
$request->uid = 0;
|
|
|
}
|
|
|
|
|
|
if($request->header('SessionId')){
|
|
|
$request->SessionId = $request->header('SessionId');
|
|
|
}
|
|
|
|
|
|
$response = $next($request);
|
|
|
|
|
|
if (isset($token)) {
|
|
|
$this->setAuthentication($response, $token);
|
|
|
}
|
|
|
|
|
|
return $response;
|
|
|
}
|
|
|
} |