extractToken($request); if (! $token) { return response()->json([ 'message' => 'Authentication required', ], 401); } $payload = $this->decodeJWT($token); if (! $payload) { return response()->json([ 'message' => 'Invalid token', ], 401); } if ($payload->exp < time()) { return response()->json([ 'message' => 'Token expired', ], 401); } $user = \App\Models\User::find($payload->sub); if (! $user) { return response()->json([ 'message' => 'User not found', ], 401); } auth()->setUser($user); $request->setUserResolver(fn () => $user); return $next($request); } protected function extractToken(Request $request): ?string { $header = $request->header('Authorization'); if (! $header || ! str_starts_with($header, 'Bearer ')) { return null; } return substr($header, 7); } protected function decodeJWT(string $token): ?object { $parts = explode('.', $token); if (count($parts) !== 3) { return null; } list($header, $payload, $signature) = $parts; $expectedSignature = hash_hmac('sha256', $header . '.' . $payload, config('app.key'), true); $expectedSignature = base64_encode($expectedSignature); $expectedSignature = str_replace(['+', '/', '='], ['-', '_', ''], $expectedSignature); if (! hash_equals($expectedSignature, $signature)) { return null; } $payload = base64_decode(str_replace(['-', '_'], ['+', '/'], $payload)); return json_decode($payload); } }