<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\JWTGuard;
class Authenticate
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param mixed ...$guards
* @return void
* @throws AuthenticationException
*/
public function handle(Request $request, Closure $next, ...$guards)
{
foreach ($guards as $guard) {
$auth = auth($guard);
if ($auth instanceof JWTGuard) {
try {
$payload = $auth->getPayload();
auth()->shouldUse($guard);
return $next($request);
} catch (TokenExpiredException $e) {
try {
$token = $auth->refresh();
$uid = $auth->factory()->buildClaimsCollection()->toPlainArray()['sub'];
$auth->onceUsingId($uid);
auth()->shouldUse($guard);
$response = $next($request);
$response->header("token", $token);
Log::info("refresh token $guard $uid");
return $response;
} catch (JWTException $exception) {
continue;
}
} catch (JWTException $e) {
continue;
}
} else if ($auth->check()) {
auth()->shouldUse($guard);
return $next($request);
}
}
throw new AuthenticationException(
'Unauthenticated.', $guards,
);
}
}
需要注意的是多个$guards如果都使用jwt,那这个判断是不准确的。只要有一个guard通过了,就验证通过了。