diff options
Diffstat (limited to 'files/ru/conflicting/web/http/cors/index.html')
-rw-r--r-- | files/ru/conflicting/web/http/cors/index.html | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/files/ru/conflicting/web/http/cors/index.html b/files/ru/conflicting/web/http/cors/index.html new file mode 100644 index 0000000000..c3d53cb730 --- /dev/null +++ b/files/ru/conflicting/web/http/cors/index.html @@ -0,0 +1,213 @@ +--- +title: Server-Side Access Control (CORS) +slug: Web/HTTP/Server-Side_Access_Control +translation_of: Web/HTTP/CORS +translation_of_original: Web/HTTP/Server-Side_Access_Control +--- +<p>Системы контроля доступа производят идентификацию <a href="http://searchsoftwarequality.techtarget.com/definition/authorization">авторизации</a>, <a href="http://searchsecurity.techtarget.com/definition/authentication">аутентификацию</a>, подтверждение доступа и подотчетность сущностей с помощью учетных данных для входа, включая <a href="http://searchsecurity.techtarget.com/definition/password">пароль</a>, личный идентификационный номер (PINs), <a href="http://searchsecurity.techtarget.com/definition/biometrics">биометрическое</a> сканирование и физический или электронный ключ.</p> + +<p>Контроль доступа --- это техника безопасности, которую можно использовать для регулирования процессом того, кто или что может видеть или использовать ресурсы в вычислительном окружении.</p> + +<p>{{HTTPSidebar}}</p> + +<p>Для меж-сайтовых запросов, произведенных с помощью {{domxref("XMLHttpRequest")}} или <a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a>, браузеры передают специальные <a href="/en-US/docs/Web/HTTP/Headers">HTTP заголовки</a>. Так же ожидаемо увидеть определенные HTTP заголовки, переданные обратно внутри меж-сайтового ответа. Обзор этих заголовков, включая примеры JavaScript кода, создающего запросы и обрабатывающего ответы от сервера, как и описание каждого из заголовков, <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS">может быть найден в статье HTTP Access Control (CORS)</a> и должен быть прочитан вместе с данной. Эта статья покрывает обработку <strong>Запросов контроля доступа</strong> и формулировку <strong>Ответов контроля доступа </strong>в PHP. Целевая аудитория для этой статьи --- разработчики серверов и администраторы. Хотя примеры кода, приведенные тут, на PHP, подобная концепция применяется в ASP.net, Perl, Python, Java, etc.; в общем, эти концепции могут быть применены в любом сервером окружении, который обрабатывает HTTP запросы и динамически формирует HTTP ответы.</p> + +<h2 id="Discussion_of_HTTP_headers">Discussion of HTTP headers</h2> + +<p>The article <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS">covering the HTTP headers used by both clients and servers is here</a>, and should be considered prerequisite reading.</p> + +<h2 id="Working_code_samples">Working code samples</h2> + +<p>The PHP snippets (and the JavaScript invocations to the server) in subsequent sections are taken from <a class="external" href="http://arunranga.com/examples/access-control/">the working code samples posted here.</a> These will work in browsers that implement cross-site {{domxref("XMLHttpRequest")}}.</p> + +<h2 id="Simple_cross-site_requests">Simple cross-site requests</h2> + +<p><a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests">Simple Access Control Requests</a> are initiated when:</p> + +<ul> + <li>An HTTP/1.1 {{HTTPMethod("GET")}} or a {{HTTPMethod("POST")}} is used as request method. In the case of a POST, the {{HTTPHeader("Content-Type")}} of the request body is one of <code>application/x-www-form-urlencoded</code>, <code>multipart/form-data</code>, or <code>text/plain.</code></li> + <li>No custom headers are sent with the HTTP request (such as <code>X-Modified</code>, etc.)</li> +</ul> + +<p>In this case, responses can be sent back based on some considerations.</p> + +<ul> + <li>If the resource in question is meant to be widely accessed (just like any HTTP resource accessed by GET), then sending back the {{HTTPHeader("Access-Control-Allow-Origin")}}<code>: *</code> header will be sufficient, <strong>unless</strong> the resource needs credentials such as <a href="/en-US/docs/Web/HTTP/Cookies">Cookies</a> and HTTP Authentication information.</li> + <li>If the resource should be kept restricted based on requester domain, <strong>OR</strong> if the resource needs to be accessed with credentials (or sets credentials), then filtering by the request's {{HTTPHeader("Origin")}} header may be necessary, or at least echoing back the requester's <code>Origin</code> (e.g. {{HTTPHeader("Access-Control-Allow-Origin")}}<code>: <a class="external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a></code>). Additionally, the {{HTTPHeader("Access-Control-Allow-Credentials")}}<code>: true</code> header will have to be sent. This is discussed in a <a class="internal" href="#Credentialed_Requests">subsequent section</a>.</li> +</ul> + +<p>The section on <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests">Simple Access Control Requests</a> shows you the header exchanges between client and server. Here is a PHP code segment that handles a Simple Request:</p> + +<pre class="brush: php"><?php + +// We'll be granting access to only the arunranga.com domain +// which we think is safe to access this resource as application/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>"; +} +?> +</pre> + +<p>The above checks to see if the {{HTTPHeader("Origin")}} header sent by the browser (obtained through $_SERVER['HTTP_ORIGIN']) matches '<a class="external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a>'. If yes, it returns {{HTTPHeader("Access-Control-Allow-Origin")}}<code>: <a class="external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a></code>. This example can be <a class="external" href="http://arunranga.com/examples/access-control/">seen running here</a>.</p> + +<h2 id="Preflighted_requests">Preflighted requests</h2> + +<p><a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">Preflighted Access Control Requests</a> occur when:</p> + +<ul> + <li>A method other than {{HTTPMethod("GET")}} or {{HTTPMethod("POST")}} is used, or if {{HTTPMethod("POST")}} is used with a {{HTTPHeader("Content-Type")}} <strong>other than</strong> one of <code>application/x-www-form-urlencoded</code>, <code>multipart/form-data</code>, or <code>text/plain</code>. For instance, if the <code>Content-Type</code> of the <code>POST</code> body is <code>application/xml</code>, a request is preflighted.</li> + <li>A custom header (such as <code>X-PINGARUNER</code>) is sent with the request.</li> +</ul> + +<p>The section on <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">Preflighted Access Control Requests</a> shows a header exchange between client and server. A server resource responding to a preflight requests needs to be able to make the following determinations:</p> + +<ul> + <li>Filtration based on {{HTTPHeader("Origin")}}, if any at all.</li> + <li>Response to an {{HTTPMethod("OPTIONS")}} request (which is the preflight request), including sending necessary values with {{HTTPHeader("Access-Control-Allow-Methods")}}, {{HTTPHeader("Access-Control-Allow-Headers")}} (if any additional headers are needed in order for the application to work), and, if credentials are necessary for this resource, {{HTTPHeader("Access-Control-Allow-Credentials")}}.</li> + <li>Response to the actual request, including handling <code>POST</code> data, etc.</li> +</ul> + +<p>Here is an example in PHP of handling a <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">preflighted request</a>:</p> + +<pre class="brush: php"><?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") { + // Tell the Client we support invocations from arunranga.com and + // that this preflight holds good for only 20 days + + 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") { + // Handle POST by first getting the XML POST blob, + // and then doing something to it, and then sending results to the client + + if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com") { + $postData = file_get_contents('php://input'); + $document = simplexml_load_string($postData); + + // do something with POST data + + $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"); +} +?> +</pre> + +<p>Note the appropriate headers being sent back in response to the {{HTTPMethod("OPTIONS")}} preflight as well as to the {{HTTPMethod("POST")}} data. One resource thus handles the preflight as well as the actual request. In the response to the <code>OPTIONS</code> request, the server notifies the client that the actual request can indeed be made with the <code>POST</code> method, and header fields such as <code>X-PINGARUNER</code> can be sent with the actual request. This example can be <a class="external" href="http://arunranga.com/examples/access-control/">seen running here</a>.</p> + +<h2 id="Credentialed_requests">Credentialed requests</h2> + +<p><a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials">Credentialed Access Control Requests</a> – that is, requests that are accompanied by <a href="/en-US/docs/Web/HTTP/Cookies">Cookies</a> or HTTP Authentication information (and which expect Cookies to be sent with responses) – can be either <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests">Simple</a> or <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">Preflighted</a>, depending on the request methods used.</p> + +<p>In a <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests">Simple Request</a> scenario, the request will be sent with Cookies (e.g. if the <code><a href="/en-US/docs/Web/API/XMLHttpRequest/withCredentials">withCredentials</a></code> flag is set on {{domxref("XMLHttpRequest")}}). If the server responds with {{HTTPHeader("Access-Control-Allow-Credentials")}}<code>: true</code> attached to the credentialed response, then the response is accepted by the client and exposed to web content. In a <a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">Preflighted Request</a>, the server can respond with <code>Access-Control-Allow-Credentials: true</code> to the <code>OPTIONS</code> request.</p> + +<p>Here is some PHP that handles credentialed requests:</p> + +<pre class="brush: php"><?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'); + + // First See if There Is a 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") { + // Tell the Client this preflight holds good for only 20 days + 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"); +} +?> +</pre> + +<p>Note that in the case of credentialed requests, the <code>Access-Control-Allow-Origin:</code> header <strong>must not</strong> have a wildcard value of "*". It <strong>must</strong> mention a valid origin domain. The example above can be seen <a class="external" href="http://arunranga.com/examples/access-control/">running here</a>.</p> + +<h2 id="Apache_examples">Apache examples</h2> + +<h3 id="Restrict_access_to_certain_URIs">Restrict access to certain URIs</h3> + +<p>One helpful trick is to use an Apache rewrite, environment variable, and headers to apply <code>Access-Control-Allow-*</code> to certain URIs. This is useful, for example, to constrain cross-origin requests to <code>GET /api(.*).json</code> requests without credentials:</p> + +<pre>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 +</pre> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a class="external" href="http://arunranga.com/examples/access-control/">Examples of Access Control in Action</a></li> + <li><a href="https://github.com/jackblackevo/cors-jsonp-sample">Client-Side & Server-Side (Java) sample for Cross-Origin Resource Sharing (CORS)</a></li> + <li><a class="internal" href="/en-US/docs/Web/HTTP/Access_control_CORS">HTTP Access Control covering the HTTP headers</a></li> + <li>{{domxref("XMLHttpRequest")}}</li> + <li><a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a></li> +</ul> |