61 lines
1.7 KiB
PHP
61 lines
1.7 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace App\Http\Middleware;
|
||
|
|
||
|
use App\Http\Controllers\Web\AuthController;
|
||
|
use App\Models\User;
|
||
|
use Closure;
|
||
|
use Exception;
|
||
|
use Firebase\JWT\JWK;
|
||
|
use Firebase\JWT\JWT;
|
||
|
use Illuminate\Http\Request;
|
||
|
use Illuminate\Support\Facades\Auth;
|
||
|
use stdClass;
|
||
|
use Symfony\Component\HttpFoundation\Response;
|
||
|
|
||
|
class JWTMiddleware
|
||
|
{
|
||
|
/**
|
||
|
* Handle an incoming request.
|
||
|
*
|
||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||
|
*/
|
||
|
public function handle(Request $request, Closure $next, string $token_type = 'id_token'): Response
|
||
|
{
|
||
|
try {
|
||
|
$jwks = (new AuthController)->getJwks();
|
||
|
} catch (Exception $e) {
|
||
|
return response()->json(['error' => 'Failed to fetch JWKS data'], 500);
|
||
|
}
|
||
|
$keys = JWK::parseKeySet($jwks);
|
||
|
|
||
|
$jwt = $request->bearerToken();
|
||
|
|
||
|
if (empty($jwt)) {
|
||
|
return response()->json(['error' => 'No token provided'], 401);
|
||
|
}
|
||
|
|
||
|
$headers = new stdClass();
|
||
|
|
||
|
try {
|
||
|
// 解码并验证 JWT
|
||
|
$decoded = JWT::decode($jwt, $keys, $headers);
|
||
|
|
||
|
if ($headers->typ != $token_type) {
|
||
|
return response()->json(['error' => 'Invalid token type, must be '.$token_type.', got '.$headers->typ], 401);
|
||
|
}
|
||
|
|
||
|
$user = User::where('external_id', $decoded->sub)->firstOrCreate([
|
||
|
'external_id' => $decoded->sub,
|
||
|
'name' => $decoded->name,
|
||
|
]);
|
||
|
|
||
|
Auth::guard('api')->loginUsingId($user->id, true);
|
||
|
} catch (Exception $e) {
|
||
|
return response()->json(['error' => 'Invalid token, '.$e->getMessage()], 401);
|
||
|
}
|
||
|
|
||
|
return $next($request);
|
||
|
}
|
||
|
}
|