--- title: Controle de Acesso do lado do servidor (CORS) slug: Web/HTTP/Server-Side_Access_Control translation_of: Web/HTTP/CORS translation_of_original: Web/HTTP/Server-Side_Access_Control ---

Os sistemas de controle de acesso realizam   identificação de autorizaçãoautenticação , aprovação de acesso e prestação de contas de entidades por meio de credenciais de login, incluindo  senhas , números de identificação pessoal (PINs),   varreduras biométricas e chaves físicas ou eletrônicas.

O controle de acesso é uma técnica de segurança que pode ser usada para regular quem ou o que pode exibir ou usar recursos em um ambiente de computação.

{{HTTPSidebar}}

Os navegadores enviam Cabeçalhos HTTP específicos para solicitações entre sites iniciadas de dentro XMLHttpRequest ou da Fetch Api . Eles também esperam ver cabeçalhos HTTP específicos enviados de volta com respostas entre sites. Uma visão geral desses cabeçalhos, incluindo amostra de código JavaScript que inicia solicitações e processa respostas do servidor, além de uma discussão sobre cada cabeçalho, pode ser encontrada no artigo HTTP Access Control (CORS) article e deve ser lida como um artigo complementar para este. Este artigo aborda o processamento de solicitações de controle de acesso e a formulação de respostas de controle de acessoem PHP. O público-alvo deste artigo são programadores ou administradores de servidores. Embora os exemplos de código mostrados aqui estejam em PHP, conceitos semelhantes se aplicam ao ASP.net, Perl, Python, Java, etc .; em geral, esses conceitos podem ser aplicados a qualquer ambiente de programação do servidor que processa solicitações HTTP e formula dinamicamente respostas HTTP.

Discussão de cabeçalhos HTTP

O artigo que cobre os cabeçalhos HTTP usados por clientes e servidores deve ser considerado leitura de pré-requisito.

Amostras de código de trabalho

Os trechos de PHP (e as invocações de JavaScript para o servidor) nas seções subseqüentes são obtidos das amostras de código de trabalho postadas aqui. Eles funcionarão em navegadores que implementam sites cruzados {{domxref("XMLHttpRequest")}}.

Solicitações simples entre sites

Solicitações simples de controle de acesso são iniciadas quando:

Nesse caso, as respostas podem ser enviadas de volta com base em algumas considerações.

A seção Solicitações de controle de acesso simples mostra as trocas de cabeçalho entre cliente e servidor. Aqui está um segmento de código PHP que lida com uma solicitação simples:

<?php

// Consideremos acesso apenas ao domínio arunranga.com
// Que achamos seguro acessar esse recurso como aplicattion / xml

if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Content-type: application/xml');
    readfile('arunerDotNetResource.xml');
} else {
  header('Content-Type: text/html');
  echo "<html>";
  echo "<head>";
  echo "   <title>Another Resource</title>";
  echo "</head>";
  echo "<body>",
       "<p>This resource behaves two-fold:";
  echo "<ul>",
         "<li>If accessed from <code>http://arunranga.com</code> it returns an XML document</li>";
  echo   "<li>If accessed from any other origin including from simply typing in the URL into the browser's address bar,";
  echo   "you get this HTML document</li>",
       "</ul>",
     "</body>",
   "</html>";
}
?>

O Origin item acima verifica se o cabeçalho enviado pelo navegador (obtido através de $ _SERVER ['HTTP_ORIGIN']]) corresponde a ' http://arunranga.com '. Se sim, ele retorna . Este exemplo pode ser visto em execução aqui . Access-Control-Allow-Origin: http://arunranga.com

Solicitações comprovadas

Solicitações de controle de acesso comprovadas ocorrem quando:

A seção Solicitações de controle de acesso comprovado mostra uma troca de cabeçalho entre cliente e servidor. Um recurso do servidor que responde a uma solicitação de comprovação precisa poder fazer as seguintes determinações:

Aqui está um exemplo no PHP de manipulação de uma solicitação preflighted :

<?php

if($_SERVER['REQUEST_METHOD'] == "GET") {

  header('Content-Type: text/plain');
  echo "This HTTP resource is designed to handle POSTed XML input";
  echo "from arunranga.com and not be retrieved with GET";

} elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
  // Diga ao cliente que apoiamos arunranga.com
  // e que esse comprovante seja válido por 20 dias

  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
    header('Access-Control-Allow-Headers: X-PINGARUNER');
    header('Access-Control-Max-Age: 1728000');
    header("Content-Length: 0");
    header("Content-Type: text/plain");
    //exit(0);
  } else {
    header("HTTP/1.1 403 Access Forbidden");
    header("Content-Type: text/plain");
    echo "You cannot repeat this request";
  }

} elseif($_SERVER['REQUEST_METHOD'] == "POST") {
  //  Manipula o post primeiro obtendo o blob XML POST
  // e, em seguida, fazendo algo e enviando resultados para o cliente

  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
    $postData = file_get_contents('php://input');
    $document = simplexml_load_string($postData);

    // Faça algo com os dados POST

    $ping = $_SERVER['HTTP_X_PINGARUNER'];

    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Content-Type: text/plain');
    echo // some string response after processing
  } else {
    die("POSTing Only Allowed from arunranga.com");
  }
} else {
    die("No Other Methods Allowed");
}
?>

Observe os cabeçalhos apropriados sendo enviados de volta em resposta à OPTIONS comprovação, bem como aos POST dados. Um recurso lida com a comprovação e com a solicitação real. Na resposta à OPTIONS solicitação, o servidor notifica o cliente de que a solicitação real pode realmente ser feita com o POST método e campos de cabeçalho como X-PINGARUNERpodem ser enviados com a solicitação real. Este exemplo pode ser visto em execução aqui .

Solicitações credenciadas

Solicitações de controle de acesso credenciadas - ou seja, solicitações acompanhadas de informações sobre cookies ou autenticação HTTP (e que esperam que os cookies sejam enviados com respostas) - podem ser simples ou comprovadas , dependendo dos métodos de solicitação utilizados.

Em um cenário de solicitação simples , a solicitação será enviada com cookies (por exemplo, se o withCredentials sinalizador estiver ativado XMLHttpRequest). Se o servidor responder com anexado à resposta credenciada, a resposta será aceita pelo cliente e exposta ao conteúdo da web. Em uma solicitação comprovada , Se o servidor responder com Access-Control-Allow-Credentials: true anexado à resposta credenciada, a resposta será aceita pelo cliente e exposta ao conteúdo da Web. Em uma Solicitação Comprovada, o servidor pode responder com Acesso-Controle-Permitir Credenciais: true à solicitação OPTIONS.

Aqui está um PHP que lida com solicitações credenciadas:

<?php

if($_SERVER['REQUEST_METHOD'] == "GET") {
  header('Access-Control-Allow-Origin: http://arunranga.com');
  header('Access-Control-Allow-Credentials: true');
  header('Cache-Control: no-cache');
  header('Pragma: no-cache');
  header('Content-Type: text/plain');

  // Primeiro, veja se existe um cookie
  if (!isset($_COOKIE["pageAccess"])) {
    setcookie("pageAccess", 1, time()+2592000);
    echo 'I do not know you or anyone like you so I am going to';
    echo 'mark you with a Cookie :-)';
  } else {
    $accesses = $_COOKIE['pageAccess'];
    setcookie('pageAccess', ++$accesses, time()+2592000);
    echo 'Hello -- I know you or something a lot like you!';
    echo 'You have been to ', $_SERVER['SERVER_NAME'], ';
    echo 'at least ', $accesses-1, ' time(s) before!';
  }
} elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
  // Diga ao cliente que esse comprovante permanece válido por apenas 20 dias
  if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") {
    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Access-Control-Allow-Methods: GET, OPTIONS');
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 1728000');
    header("Content-Length: 0");
    header("Content-Type: text/plain");
  } else {
    header("HTTP/1.1 403 Access Forbidden");
    header("Content-Type: text/plain");
    echo "You cannot repeat this request";
  }
} else {
  die("This HTTP Resource can ONLY be accessed with GET or OPTIONS");
}
?>

Observe que, no caso de solicitações credenciadas, o Access-Control-Allow-Origin: cabeçalho não deve ter um valor curinga de "*". Ele deve mencionar um domínio de origem válido. O exemplo acima pode ser visto em execução aqui .

Exemplos do Apache

Restringir o acesso a determinados URIs

Um truque útil é usar uma reescrita do Apache, variável de ambiente e cabeçalhos para aplicar Access-Control-Allow-*a determinados URIs. Isso é útil, por exemplo, para restringir solicitações de origem cruzada a GET /api(.*).jsonsolicitações sem credenciais:

RewriteRule ^/api(.*)\.json$ /api$1.json [CORS=True]
Header set Access-Control-Allow-Origin "*" env=CORS
Header set Access-Control-Allow-Methods "GET" env=CORS
Header set Access-Control-Allow-Credentials "false" env=CORS

Veja também