분류

2019년 1월 18일 금요일

Iframe 을 이용한 cross - domain 메시지 교환

하나의 세션에 대한 인증 결과와 경과 시간에 대한 주기적인 체크를 할 수 있는 방법이 필요했습니다.

여러 다른 url을 가진 사이트간의 통신은 cross-domain 보안 정책에 의해 기본적으로 차단되어 있는 상황에서 보안정책을 변경하는 것 보단 간단한 메시지를 전달하는 정도의 방식으로 프로그래밍을 하는 것이 수월하기에 iframe을 이용해 서로 다른 도메인간의 통신을 유도하는 방법을 찾아보았습니다.

일단 메시지를 보내는 주 사이트와, 메시지를 받는 사이트 측으로 분리해서 아래와 같은 스크립트를 만들어보았습니다.

크로스 도메인을 위한 스크립트 구성 

부모페이지에 추가된 script (메시지를 받는 쪽)
//iframe를 첨부할 jsp 내에 아래와 같은 스크립트와 iframe을 추가합니다. 

<script type="text/javascript">
//iframe에서 전송하는 메시지를 받을 리스너를 생성 
//(iframe과 동일한 페이지 현재 스크립트가 있어야함)
function receiveMessage(event){
//리스너 이벤트 전송자와, 명령어가 동일할 경우 수행 
if(event.data === "testMessage" && event.origin === "http://testsite"){ 
//event.data는 리스너를 통해 전달받는 데이터입니다. 
// ===은 데이터 타입과 데이터 내용이 모두 일치하는지 비교하는 연산자 
//event.origin은 지정된 주소를 입력하여 지정된 도메인에서 발신한 것인지 확인합니다.
alert("메시지 전달 받았습니다.");//메시지 수신 후 실행할 스크립트를 입력합니다.
}
}
//현재창에 메시지 이벤트 리스너를 추가 
window.addEventListener("message", receiveMessage); 
</script>
//현재창에 메시지 이벤트 리스너를 추가 
<iframe id="test" name="test" src="http://testsite/innerFrame.jsp"></iframe>

메시지를 주는 쪽인 http://testsite/의 innerFrame.jsp
<script type="text/javascript">
var parent = window.parent; 
if(parent && parent.postMessage){
        //postMessage("전송메시지","전송 도메인") 
parent.postMessage("testMessage",  "*");
}else{
console.log("post Message is not allow"); 
}
</script>

위와 같은 비교적 단순한 구성을 통해 서로 다른 도메인 간의 메시지를 주고받을 수 있습니다.

postMessage 함수는 메시지와 함께 전송할 대상 도메인을 특정할 수 있습니다. 이유는 불필요한 도메인에서 해당 소스를 붙여 메시지를 가로채거나 하는 문제를 방지하기 위해서 입니다.

이 스크립트는 iframe내부 문서와 부모창의 구성을 바꿔서 사용할 수도 있습니다.

postMessage구성 

postMessage(메시지, 대상도메인)

메시지 : 다른 창으로 보낼 데이터를 담는 부분입니다. (구조화된 복제 알고리즘을 통해 정해진 양식으로 변형되어 전송된다고 합니다. )

대상도메인 : "*"을 입력한경우 대상을 특정하지 않고 아무에게나 보내는 것입니다. 공개된 메시지가 되는 것이므로, 중요한 데이터를 보내면 위험할 수 있습니다. 아무나 iframe을 사용하여 메시지를 확인할 수 있으니까요.
사용 예) document.postMessage("메시지", "http://test.kr") 의 형태로 메시지를 보낼경우 http://test.kr이 아닌 도메인에선 해당 메시지를 확인할 수 없습니다. 

SANDBOX 


HTML5에서는 SANDBOX라는 속성이 생겼습니다. 이것을 이용해 크로스도메인 정책을 우회할 수 있다는 인터넷의 일부 문서를 확인했습니다만. 적용결과 실패하였습니다. 안됩니다.

샌드박스 속성과 값 

1. (값없음)                   모든 제한 사항 적용
2. allow-forms               폼 전송을 사용할 수 있습니다.(form.submit())
3. allow-pointer-lock       api를 사용할 수 있습니다.
4. allow-popups             팝업을 사용할 수 있습니다.
5. allow-same-origin        iframe내부의 콘텐츠가 같은 도메인으로 취급됩니다.
6. allow-scripts               스크립트를 사용할 수 있습니다.
7. allow-top-navigation     iframe 내부 콘텐츠가 top.document의 location을 제어할 수 있습니다.

위와 같은 태그 속성이 있고 iframe을 선언할 때 사용하는 코드입니다. 사용방법은 아래와 같습니다.
1. (값없음)  <iframe sandbox src=""> </iframe>
2. allow-forms   <iframe sandbox="allow-forms" src=""> </iframe>
3. 복합 <iframe sandbox="allow-forms allow-top-navigation" src="">  </iframe>

단일 속성을 사용할 수도 있고, 복합 속성을 사용할 수도 있습니다. allow-same-origin  의 경우 서로 다른 도메인일 경우에도 같은 출처로 취급할 수 있다고 설명되어있지만, 실제 사용결과는 다음 오류가 발생합니다.

예) iframe 내에서 top.window.document.reload()를 수행한경우 오류
Uncaught DOMException: Blocked a frame with origin "" from accessing a cross-origin frame.

도메인이 다르기 때문에 발생하는 오류입니다. 이것이 postMessage를 사용하게 된 이유이기도 합니다. 같은 도매인 내에서의 iframe호출은 성공적이었지만, 서로 다른 도메인에 적용한 결과 위와 같은 오류가 발생하여 사용할 수 없습니다.

w3schools에서는 모든 브라우저에서 적용된다고 되어있지만, 실제로 되지 않고 있습니다. 이유를 아시는 분이 계신다면 댓글을 달아주시면 감사하겠습니다.


댓글 없음:

댓글 쓰기