Можно ли прочитать document.body вторичного окна, которое находится в другом домене, используя postMessage()?
Я создаю веб-приложение: SPA, используя React во фронтенде и Django rest framework для конечных точек API.
Я занимаюсь частью социального логина, который делается полностью в бэкенде (происходит обмен токенами провайдеров по собственным JWT), поэтому необходимо сделать запрос к серверу, который перенаправляет пользователя на логин конкретного провайдера. Однако из-за того, что Facebook, Google и другие провайдеры не разрешают выполнять этот запрос с помощью AJAX, я решил создать всплывающее окно (через window.open()
), чтобы выполнить это перенаправление.
В случае успешного входа это окно снова перенаправляется на представление Django, которое возвращает JSON с JWT. Следовательно, это вторичное окно имеет JWT в домене моего сервера (Django).
Я планировал прочитать этот JSON из тела этого вторичного окна, чтобы получить JWT, и я читаю (Code response form parent window, SecurityError: Blocked... и другие), что единственный способ связи окон в разных доменах - это postMessage()
. Но когда я пытаюсь, я получаю следующее сообщение:
SecurityError: Отказано в разрешении на доступ к свойству "document" на кросс-оригинального объекта
На самом деле они оба запущены на localhost, только с разными портами. Именно по этой причине активирована политика одинакового происхождения.
Пример моей кнопки для открытия окна входа в социальную сеть.
<button
className="facebookI"
title="Facebook"
type="button"
onClick={loginSocial}
>
<i className="fab fa-facebook-f" title="Facebook"></i>
</button>
Функции, которые управляют нажатием и осуществляют попытку чтения.
const loginSocial = ({target}) => {
let socialWindow = null;
socialNetwork = target.title.toLowerCase();
request = `/kuku_api/social-auth/login/${socialNetwork}/`;
if(socialWindow === null || socialWindow.closed) // If there is no window open
socialWindow = openWindow(request, width, height, x, y);
main = socialWindow.opener;
// I coded a setTimeout to made the next after the login
main.postMessage(socialWindow?.document?.body, 'http://local.react:3000');
}
const openWindow = (request, width, height, x, y) => {
return window.open(
'http://local.django:8000' + request,
'SocialLogin',
'popup,location,width=' + width + ',height=' + width + ',left=' + x + ',top=' + y + ''
);
}
И слушатель "сообщения".
useEffect(() =>{
window.addEventListener('message', handleMessage);
return () => ( window.removeEventListener('message', handleMessage) );
}, []);
const handleMessage = (e) => {
if(e.origin !== 'http://local.react:3000'){
return;
}
console.log(`Test ${e?.origin}`);
console.log(`Test ${e?.source}`);
console.log(`Test ${e?.data}`);
};
Где моя ошибка? Или есть способ прочитать этот JWT из тела вторичного окна?
Возможно, я выбрал неправильный подход. Пожалуйста, не стесняйтесь делать предложения о том, как достичь этого лучшим способом.