amber-laravel/app/Http/Middleware/JWTMiddleware.php

61 lines
1.7 KiB
PHP
Raw Permalink Normal View History

2024-07-23 16:40:56 +00:00
<?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);
}
}