Что касается междоменного доступа,два недоразумения:
1. ✕ Динамические запросы будут иметь междоменные проблемы
✔ Междоменный доступ существует только на стороне браузера, а не в других средах, таких как Android/ios/Node.js/python/java.
2. ✕ Междоменное означает, что запрос не может быть отправлен
✔ Может быть отправлен междоменный запрос, сервер может принять запрос и вернуть результат нормально, но результат перехватывается браузером
Причина, по которой он является междоменным, заключается в том, что он ограничен политикой одного и того же источника, которая требует, чтобы один и тот же источник для нормальной связи, то есть протокол, имя домена и номер порта были одинаковыми.
Как показано ниже:
Эти три источника ограничены политикой одного источника из-за несогласованных доменных имен, протоколов и номеров портов.
Каковы конкретные ограничения политики одного и того же происхождения?
1. Нельзя запрашивать данные у сервисов, которые работают на разных источниках (клиент-сервер)
Здесь есть вопрос, который меня давно беспокоит, а именно, почему cdn.home.com/index.js, загруженный home.com, может отправлять запросы на home.com без кроссдоменности? На самом деле, JS, загруженный с home.com, работает на home.com, а его источник не является cdn, предоставляющим JS, поэтому в настоящее время нет междоменной проблемы, и тег script может загружать не то же происхождение. ресурсы, не будучи затронуты одним и тем же источником влияния стратегии.
2. Невозможно получить BOM и DOM документов/куки из разных источников Можно сказать, что невозможно получить какую-либо информацию о другом источнике (клиент к клиенту)
Почему существует политика того же происхождения?
1. Зачем ограничивать запросы из разных источников?
Предполагая, что пользователь заходит на bank.com и одновременно открывает evil.com, если нет ограничений, evil.com может запрашивать любую информацию с bank.com, а затем может отправлять запросы на перевод на bank.com от evil .ком.
Если да, то почему бы просто не ограничить запись и не ограничить только чтение?
Потому что, если запрос не может быть отправлен, междоменное совместное использование ресурсов не может быть выполнено, а возвращенный результат не может быть прочитан, и evil.com не может продолжить следующую операцию, такую как получение некоторой необходимой проверочной информации для запроса на передачу.
2. Зачем ограничивать междоменное чтение DOM?
Если ограничений нет, то легко замаскировать другие веб-сайты, например, установив iframe или используя метод window.open, чтобы получить действия и ввод пользователя, такие как учетная запись и пароль.
Кроме того, добавьте этот http-заголовок, чтобы запретить другим помещать ваш сайт в его iframe:
X-Frame-Options: SAMEORIGIN
Политика одного и того же источника обеспечивает безопасность, но также вызывает неудобства, поскольку иногда нам необходимо выполнять междоменные запросы, например, для получения служебной информации, предоставленной третьей стороной, поскольку источник третьей стороны отличается от источника этого веб-сайта, поэтому в настоящее время на нас распространяются междоменные ограничения.
Наиболее распространенным методом междоменного доступа должен бытьCORS,Как показано ниже:
Пока браузер обнаруживает, что заголовок ответа содержит CORS, а разрешенный источник включает этот веб-сайт, ответ на запрос не будет перехвачен.
CORS делит запросы на два типа: один — простой запрос, а другой — запрос, который необходимо инициировать.предварительный запрос, эти два относительные, что считать "не простым"? Это не простой запрос, если он относится к одному из следующих:
(1) Используются методы запроса, отличные от GET/POST/HEAD, такие как PUT/DELETE.
(2) Используется несколько часто используемых заголовков http, кроме Content-Type/Accept.
В настоящее время считается, что сначала необходимо отправить запрос на предварительную проверку.Запрос на предварительную проверку использует метод OPTIONS для проверки безопасности текущего запроса, как показано на следующем рисунке:
В коде только один запрос, но я вижу в консоли два запроса, первый это OPTIONS, и сервер возвращает:
Заголовок возврата содержит разрешенные заголовки запроса, методы запроса, источники и срок действия предварительного запроса. На приведенном выше рисунке установлено значение 20 дней. В течение этого срока действия нет необходимости отправлять еще один запрос параметров. Фактически, у браузера максимальное долгое время, как у Chrome, составляет 5 минут. Если предварительный запрос обнаружит, что текущий запрос не соответствует требованиям, установленным сервером, он не будет отправлять исключение, а сразу выдаст исключение.В настоящее время нет необходимости отправлять «сложный» запрос.
Если источник находится за пределами допустимого диапазона источников, будет выдано исключение, и возвращаемый результат не может быть получен:
Для поддержки CORS nginx можно настроить так:
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}
Второй широко используемый междоменный метод —JSONP, JSONP использует тег script для междоменного взаимодействия, как показано в следующем коде:
function updateList (data) {
console.log(data);
}
$body.append(‘<script src=“http://otherdomain.com/request?callback=updateList"></script>');
Код сначала определяет глобальную функцию, а затем добавляет имя функции в src тега скрипта через параметр обратного вызова, src скрипта — это запрос, который должен быть междоменным, а затем запрос возвращает исполняемый JS текст:
// script响应返回的js内容为
updateList([{
name: 'hello'
}]);
Поскольку это js и определена функция updateList, она может выполняться в обычном режиме, а междоменные данные получаются путем передачи параметров. Это принцип JSONP.
Таким образом, поскольку запросы тегов, таких как script/iframe/img, могут содержать файлы cookie по умолчанию (файл cookie содержит токен билета для проверки входа), выполнение запросов с этими тегами может обойти политику одного и того же источника, поэтому вы можете использовать эти теги. ДелатьПодделка межсайтовых запросов (CSRF), как показано в следующем коде:
// 转账请求
<iframe src="http://Abank.com/app/transferFunds?amount=1500&destinationAccount=..."></iframe>
// 配置路由器添加代理
<img src="http://192.168.1.1/admin/config/outsideInterface?nexthop=123.45.67.89" style="display:none">
Если соответствующий веб-сайт поддерживает запросы GET или не принимает дополнительных мер защиты, то, если пользователь вошел в систему на другой странице, а затем открыл «токсичный» веб-сайт, он будет обманут.
Динамический запрос ajax по умолчанию не содержит файлы cookie. Если вы хотите использовать файлы cookie, вы можетеУстановите свойство ajax withCredentials, как показано в следующем коде:
// 原生请求
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open("GET", "http://otherdomain.com/list");
xhr.send();
// jquery请求
$.ajax({
url: "http://otherdomain.com/list",
xhrFields: {
withCredentials: true
}
});
В настоящее время, как и тег img/script, он может содержать файлы cookie, а также поддерживает другие методы, кроме GET. Следовательно, этот метод также может реализовать CSRF, как показано на следующем рисунке:
Поэтому, если запрос на передачу просто не поддерживает GET и не предпринимаются никакие другие защитные меры, риск CSRF-атаки сохраняется. тогда что нам делать?
Первый способ заключается в отображении тикета с токеном в параметре для каждого запроса.Хотя междоменный запрос может принести куки, куки из других источников нельзя получить через document.cookie, поэтому злоумышленник не может куки получается в коде, так что никак. Недостаток метода 1 в том, что токен будет выставлен, поэтому лучше не использовать GET с токеном, т.к. GET пропишет параметры в url, и пользователь может непреднамеренно отправить ссылку другим, а он не знать, что ссылка имеет свою собственную информацию для входа.
Второй метод заключается в запросе случайной строки перед каждым запросом на перевод. Эта строка может использоваться только для одного запроса на перевод или платеж, и она будет отброшена, когда она будет израсходована. Запрос может быть успешным только в том случае, если строка совпадает. , потому что, если междоменный запрос с файлом cookie, браузер требует, чтобы Access-Control-Allow-Origin не был подстановочным знаком, а мог быть только указанным источником, например:
Access-Control-Allow-Origin: http://renren.com
add_header "Access-Control-Allow-Origin" "http://fedren.com";
add_header "Access-Control-Allow-Credentials" "true";
Есть еще две вещи, которые стоит отметить в отношении файлов cookie, как показано на следующем рисунке:
iframe может получить доступ к родительской странице черезwindow.parentПолучить объект окна родительского окна, которое можно открыть с помощью openwindow.opener, а затем получить что-либо из родительского окна; если родительское окно имеет то же происхождение, что и iframe, вы можете получить объект окна iframe через iframe.contentWindow. Если он отличается от iframe, существует кросс- проблема с доменом.postMessageобщаться.
Основной принцип использования PostMessage показан на следующем рисунке:
// main frame
let iframeWin = document.querySelector("#my-iframe")
.contentWindow;
iframeWin.postMessage({age: 18}, "http://parent.com");
iframeWin.onmessage = function(event) {
console.log("recv from iframe ", event.data);
};
// iframe
window.onmessage = function(event) {
// test event.origin
if (event.origin !== expectOrigin) {
return;
}
console.log("recv from main frame ", event.data);
};
window.parent.postMessage("hello, this is from iframe ", "http://child.com");
Взяв в качестве примера страницу со встроенным видео youtobe, следующий код может встроить видео youtobe на страницу, которая является междоменным iframe, поэтому он включает в себя способ взаимодействия с iframe. Как узнать статус iframe, вызвать событие onPlayerReady, определенное родительской страницей, это iframe, уведомляющий родительскую страницу, и родительская страница может настроить player.stopVideo для управления поведением iframe, это родительская страница уведомление iframe.
iframe уведомляет родительскую страницу через window.parent.postMessage и прослушивает событие сообщения:
После проверки c в строке 4304 приведенного выше кода является window.parent, этот embed-player.js является js iframe, а js iframe отправляет сообщение через postMessage, как показано в окне справа. на рисунке выше, а затем в widgetapi.js родительского окна Только что получил это сообщение.
Точно так же JS родительского окна также использует postMessage для отправки сообщений в iframe, как показано на следующем рисунке:
Конечно, postMessage не ограничивается кроссдоменностью, его можно использовать и в том же домене, но в том же домене вы можете взаимодействовать друг с другом через объект окна.Возможно, вам потребуется определить какие-то дополнительные глобальные переменные или функции для использования другими фреймами или определить набор механизмов событий (вы можете использовать помощь нативных событий/событий jQuery/Vue и т. д.).
Здесь есть особый случай, то есть, когда поддомен, такой как mail.hello.com, хочет пересечь hello.com, вы можете явно установить document.domain поддомена в домен родительского домена:
document.domain = "hello.com";
window.addEventListener('storage', function(e) {
e.key;
e.oldValue;
e.newValue;
e.url;
e.storageArea;
});
Я не пробовал, но читатели могут попробовать.
Еще одна вещь, которую следует добавить, веб-сокет не ограничен политикой одного и того же происхождения, и нет проблем с междоменными связями. Файлы шрифтов CSS будут иметь междоменные проблемы. Указание CORS может загружать файлы шрифтов из других источников (обычно размещенных в CDN). Внешнее изображение, динамически загружаемое холстом, также должно указывать заголовок CORS для обработки изображения, в противном случае его можно будет только отрисовать, но нельзя прочитать.
Наконец, междоменные запросы делятся на два типа: один — это междоменный запрос, а другой — доступ к междоменным страницам. в основном через postMessage. Поскольку междоменные запросы могут не только отправляться, но и содержать файлы cookie, необходимо избегать риска атак с подделкой межсайтовых запросов, особенно тех, которые связаны с деньгами.