CORS の設定

クロスオリジンリソース共有 (CORS) は、許可された Web ページから、その Web ページを提供しているドメインとは異なるドメインへのリクエストを行うことを許可または制限する、Web ブラウザで実装されたセキュリティ機能です。

これは、特定のドメインの外部に配置されたリソースへの制御されたアクセスを可能にするメカニズムです。

CORS は、悪意のあるクロスオリジンリクエストを防止しながら、異なる Web アプリケーション間のセキュアな通信を可能にするために不可欠です。

特定のヘッダーを指定することで、サーバーはどのオリジンがそのリソースにアクセスできるかを指定でき、それにより使いやすさとセキュリティのバランスを保ちます。

CORS サポートを実装するための、優れたフローチャート: CORS サーバーフローチャート

仕様はこちらで読むことができます: https://fetch.spec.whatwg.org/#cors-protocol

簡単な解決策

簡単な CORS リクエストの場合、サーバーはそのレスポンスに次のヘッダーを追加する必要があります

Access-Control-Allow-Origin: <domain>, ... 

次のコードは、遅延 CORS を有効にできます。

$app->options('/{routes:.+}', function ($request, $response, $args) {
    return $response;
});

$app->add(function ($request, $handler) {
    $response = $handler->handle($request);
    return $response
            ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
            ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
            ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
});

オプション: 最後のルートとして次のルートを追加します

use Slim\Exception\HttpNotFoundException;

/**
 * Catch-all route to serve a 404 Not Found page if none of the routes match
 * NOTE: make sure this route is defined last
 */
$app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function ($request, $response) {
    throw new HttpNotFoundException($request);
});

CORS のサンプルアプリケーション

CORS ミドルウェアを使用する、 完全な CORS サンプルアプリケーションです

<?php

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Factory\AppFactory;

require_once __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->addBodyParsingMiddleware();

// Add the RoutingMiddleware before the CORS middleware
// to ensure routing is performed later
$app->addRoutingMiddleware();

// Add the ErrorMiddleware before the CORS middleware
// to ensure error responses contain all CORS headers.
$app->addErrorMiddleware(true, true, true);

// This CORS middleware will append the response header
// Access-Control-Allow-Methods with all allowed methods
$app->add(function (ServerRequestInterface $request, RequestHandlerInterface $handler) use ($app): ResponseInterface {
    if ($request->getMethod() === 'OPTIONS') {
        $response = $app->getResponseFactory()->createResponse();
    } else {
        $response = $handler->handle($request);
    }

    $response = $response
        ->withHeader('Access-Control-Allow-Credentials', 'true')
        ->withHeader('Access-Control-Allow-Origin', '*')
        ->withHeader('Access-Control-Allow-Headers', '*')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
        ->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
        ->withHeader('Pragma', 'no-cache');

    if (ob_get_contents()) {
        ob_clean();
    }

    return $response;
});

// Define app routes
$app->get('/', function (ServerRequestInterface $request, ResponseInterface $response) {
    $response->getBody()->write('Hello, World!');
    
    return $response;
});

// ...

$app->run();

Access-Control-Allow-Credentials

リクエストに資格情報 (Cookie、認可ヘッダー、または TLS クライアント証明書)が含まれる場合、レスポンスオブジェクトに Access-Control-Allow-Credentials ヘッダーを追加する必要があります。

$response = $response->withHeader('Access-Control-Allow-Credentials', 'true');