first init
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiKeyAuthenticationMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
// Check if API key authentication is enabled
|
||||
if (!config('api_security.enable_api_key_auth', true)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// Get API key from request
|
||||
$apiKey = $this->extractApiKey($request);
|
||||
|
||||
if (!$apiKey) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'API key is required for external system access.',
|
||||
'error' => 'API_KEY_REQUIRED'
|
||||
], 401);
|
||||
}
|
||||
|
||||
// Validate API key
|
||||
if (!$this->isValidApiKey($apiKey)) {
|
||||
// Log invalid API key attempt
|
||||
if (config('api_security.log_api_key_usage', true)) {
|
||||
Log::warning('Invalid API key attempt', [
|
||||
'ip' => $request->ip(),
|
||||
'user_agent' => $request->header('User-Agent'),
|
||||
'endpoint' => $request->fullUrl(),
|
||||
'method' => $request->method(),
|
||||
'api_key_prefix' => substr($apiKey, 0, 8) . '...',
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid API key provided.',
|
||||
'error' => 'API_KEY_INVALID'
|
||||
], 401);
|
||||
}
|
||||
|
||||
// Log successful API key usage
|
||||
if (config('api_security.log_api_key_usage', true)) {
|
||||
Log::info('API key authenticated', [
|
||||
'ip' => $request->ip(),
|
||||
'user_agent' => $request->header('User-Agent'),
|
||||
'endpoint' => $request->fullUrl(),
|
||||
'method' => $request->method(),
|
||||
'api_key_prefix' => substr($apiKey, 0, 8) . '...',
|
||||
]);
|
||||
}
|
||||
|
||||
// Add API key info to request for downstream use
|
||||
$request->merge(['_api_key' => $apiKey]);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract API key from request headers
|
||||
*/
|
||||
private function extractApiKey(Request $request): ?string
|
||||
{
|
||||
// Check multiple header formats
|
||||
$apiKeyHeaders = config('api_security.api_key_headers', [
|
||||
'X-API-Key',
|
||||
'API-Key',
|
||||
'Authorization'
|
||||
]);
|
||||
|
||||
foreach ($apiKeyHeaders as $header) {
|
||||
$value = $request->header($header);
|
||||
|
||||
if ($value) {
|
||||
// Handle Bearer token format
|
||||
if ($header === 'Authorization' && preg_match('/Bearer\s+(.*)$/i', $value, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
// Direct API key
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate API key against configured valid keys
|
||||
*/
|
||||
private function isValidApiKey(string $apiKey): bool
|
||||
{
|
||||
$validApiKeys = config('api_security.valid_api_keys', []);
|
||||
|
||||
if (empty($validApiKeys)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($apiKey, $validApiKeys);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user