* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace App\Http\Middleware; use App\Repositories\Enums\ResponseCodeEnum; use App\Support\Traits\LoginLimit; use Closure; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\Exceptions\TokenInvalidException; use Tymon\JWTAuth\Http\Middleware\BaseMiddleware; //class Authenticate extends BaseMiddleware class Authenticate { use LoginLimit; public function __construct(\Illuminate\Contracts\Auth\Factory $auth) { $this->auth = $auth; } /** * Handle an incoming request. * * @param Request $request * @param Closure $next * @param string|null $guard * @return mixed * * @throws AuthorizationException */ public function handle($request, Closure $next, $guard = null) { // Auth::setDefaultDriver($guard); // try { // // 检查此次请求中是否带有 token,如果没有则抛出异常。 // $this->checkForToken($request); // } catch (TokenInvalidException $exception) { // abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, 'token有误'); // } // // //1. 格式通过,验证是否是专属于这个的token // //获取当前守护的名称 // $guard = Auth::getDefaultDriver(); // Log::error("1"); // //使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常 // //2. 此时进入的都是属于当前guard守护的token // try { // // 检测用户的登录状态,如果正常则通过 // if ($this->auth->parseToken()->authenticate()) { // Log::error("2"); // $token = Auth::getToken(); // $user_id = $this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']; // //单机登录检查 // if (!$this->singleLoginCheck($token, $user_id, $guard)) { // Log::error("3"); // abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, '该账号已经再其他设备上登录'); // } // Log::error("4"); // return $next($request); // } // Log::error("5"); // abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, 'token过期,请重新登陆。'); // } catch (TokenExpiredException $exception) { // // 3. 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中 // try { // Log::error("6"); // // 刷新用户的 token // $token = $this->auth->refresh(); // // 使用一次性登录以保证此次请求的成功 // $user_id = $this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']; // Auth::onceUsingId($user_id); // // $this->singleLoginSetToken($user_id, $token, $guard); // Log::error("7"); // return $this->setAuthenticationHeader($next($request), $token); // } catch (JWTException $exception) { // Log::error("8"); // Log::error($exception); // // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。 // abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, 'token令牌过期,请重新登陆。'); // } // } // Log::error("9"); // // 在响应头中返回新的 token // abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, '异常错误-Mead'); if ($this->auth->guard($guard)->guest()) { abort(ResponseCodeEnum::HTTP_UNAUTHORIZED); } $token = Auth::getToken(); $user_id = $this->auth->guard($guard)->id(); //单机登录检查 if (!$this->singleLoginCheck($token, $user_id, $guard)) { Log::error("3"); abort(ResponseCodeEnum::HTTP_UNAUTHORIZED, '该账号已经再其他设备上登录'); } return $next($request); } }