php-cors

repository·master·Indexed 43 days ago

https://github.com/fruitcake/php-cors

A library and middleware for enabling Cross-Origin Resource Sharing (CORS) in PHP applications using Symfony HttpFoundation. It implements the W3C recommendation for CORS and provides the CorsService to handle preflight requests, validate origins, and apply CORS headers to responses.

Tokens
1.8K
Snippets
6
Records
7
Agent score
6%

What's inside php-cors

  1. Configure CorsService options

    master

    The Fruitcake\Cors\CorsService is configured using an associative array of options. These options control how CORS headers are applied and which requests are permitted.

    OptionDescriptionDefault
    allowedMethodsMatches the request method (case-insensitive).[]
    allowedOriginsMatches the request origin. A wildcard * allows all origins.[]
    allowedOriginsPatternsMatches the request origin using preg_match.[]
    allowedHeadersSets the Access-Control-Allow-Headers response header (case-insensitive).[]
    exposedHeadersSets the Access-Control-Expose-Headers response header.[]
    maxAgeSets the Access-Control-Max-Age response header.0
    supportsCredentialsSets the Access-Control-Allow-Credentials header.false

    Key Behaviors

    • Origins: You do not need to provide both allowedOrigins and allowedOriginsPatterns. If a string in either matches, the origin is considered valid. A wildcard in allowedOrigins will be automatically converted to a pattern.
    • Wildcards: Providing ['*'] to allowedMethods, allowedOrigins, or allowedHeaders allows all possible values for that category.
    • Cacheability: For better cacheability, prefer allowing a single static origin rather than using patterns where possible.
    $cors = new CorsService([
        'allowedHeaders'         => ['x-allowed-header'],
        'allowedMethods'         => ['GET', 'POST'],
        'allowedOrigins'         => ['https://example.com'],
        'allowedOriginsPatterns' => ['/localhost:\d/'],
        'exposedHeaders'         => ['Content-Encoding'],
        'maxAge'                 => 3600,
        'supportsCredentials'    => false,
    ]);
  2. Use CorsService to handle CORS requests

    master

    The CorsService provides methods to inspect requests and apply headers to responses. It is designed to work with Symfony Request and Response objects.

    Core Methods

    • $cors->addActualRequestHeaders(Response $response, $origin): Adds the necessary CORS headers to the response for an actual request.
    • $cors->handlePreflightRequest(Request $request): Handles the logic for an OPTIONS preflight request.
    • $cors->isActualRequestAllowed(Request $request): Checks if the current request is an actual request that complies with the configured CORS policy.
    • $cors->isCorsRequest(Request $request): Determines if the incoming request is a CORS request.
    • $cors->isPreflightRequest(Request $request): Determines if the incoming request is a preflight (OPTIONS) request.
    <?php
    
    use Fruitcake\
    Cors\\CorsService;
    
    $cors = new CorsService([
        'allowedHeaders'         => ['x-allowed-header', 'x-other-allowed-header'],
        'allowedMethods'         => ['DELETE', 'GET', 'POST', 'PUT'],
        'allowedOrigins'         => ['http://localhost', 'https://*.example.com'],
        'allowedOriginsPatterns' => ['/localhost:\d/'],
        'exposedHeaders'         => ['Content-Encoding'],
        'maxAge'                 => 0,
        'supportsCredentials'    => false,
    ]);
    
    // Example usage with Symfony Request/Response objects
    $cors->addActualRequestHeaders($response, $origin);
    $cors->handlePreflightRequest($request);
    $cors->isActualRequestAllowed($request);
    $cors->isCorsRequest($request);
    $cors->isPreflightRequest($request);
  3. Check if an origin is allowed

    master

    You can manually verify if the Origin header in a Request matches your configured allowed origins using isOriginAllowed(Request $request). This is useful if you want to implement custom logic before proceeding with the request.

    if ($cors->isOriginAllowed($request)) {
        // Proceed with request
    } else {
        // Handle unauthorized origin
    }
  4. Identify CORS and Preflight requests

    master

    The CorsService provides helper methods to detect the type of incoming request:

    • isCorsRequest(Request $request): Returns true if the request contains an Origin header.
    • isPreflightRequest(Request $request): Returns true if the request is an OPTIONS method and contains the Access-Control-Request-Method header.
  5. Handle CORS preflight requests

    master

    When a browser sends an OPTIONS request (a preflight request), you can use CorsService to generate a valid 204 No Content response with the appropriate CORS headers.

    Use handlePreflightRequest(Request $request) to automatically create a response that includes Access-Control-Allow-Methods, Access-Control-Allow-Headers, and other necessary preflight headers based on your configuration.

    // Assuming $request is a Symfony
    // Component
    // 
    //HttpFoundation
    // Request instance
    
    $cors = new \Fruitcake\Cors\CorsService($options);
    
    if ($cors->isPreflightRequest($request)) {
        $response = $cors->handlePreflightRequest($request);
        // Return $response to the client
    }
  6. Add CORS headers to actual requests

    master

    For standard HTTP requests (not preflights), use addActualRequestHeaders(Response $response, Request $request) to inject the necessary CORS headers into your existing Symfony Response object. This ensures that the Access-Control-Allow-Origin, Access-Control-Allow-Credentials, and Access-Control-Expose-Headers headers are correctly set based on the incoming request's origin and your service configuration.

    $cors = new \Fruitcake\Cors\CorsService($options);
    $response = new \Symfony\Component\HttpFoundation\Response('Hello World');
    
    // Add CORS headers to the existing response
    $response = $cors->addActualRequestHeaders($response, $request);