electron.js
를 이용해서 데스크탑 앱을 만들 때나, 웹뷰를 이용한 하이브리드 앱을 구축하려면 웹뷰와 네이티브 앱이 통신하는 방법이 필요하다. 이 때 가장 일반적으로 사용하는 방법이 브라우저에서 제공하는 Window
인터페이스를 사용하는 방식인데, 그래서 Window
인터페이스에 대해서 한번 정리해보기로 했다.
예를 들어 안드로이드 기반 하이브리드 어플리케이션을 만들었다고 생각해 보자.
일반적으로 안드로이드에서는 '뒤로가기 버튼' 을 클릭 했을때 앱의 페이지 상에서 뒤로가기가 된
다. 그리고 앱의 최상단 화면에서 뒤로가기를 누르면 앱이 꺼진다.
이러한 기능을 웹뷰를 이용해서 구현하려면 어떻게 해야할까?
이를 구현하기 위한 방법이 Window
인터페이스에 사용자 정의 함수를 등록하는 것과, Window.postmessage
를 이용하는 것이다.
위의 상황에서 뒤로가기를 잘 구현하려면 우선 웹상에서 사용자가 뒤로가기 버튼을 눌렀다는 것을 알아야 한다. 이를 위해서 우리는 window
에 handleAndroidBackButtonPress()
라는 함수를 달아 줄 것이다.
이를 구현하는 방법은 사실 간단하다.
일반 객체에 함수를 달듯이, 이렇게 달아주면 된다.
window.handleAndroidBackButtonPress() = (
function() {
...
}
)
그러면 모바일 앱에서 웹뷰 객체에 대해 handleAndroidBackButtonPress()
를 호출 할 수 있다.
Typescript를 사용할 경우 window object does not have property handleAndroidBackButtonPress...
에러가 뜰텐데, 이를 해결하기 위한 방법들 중 2가지를 소개한다.
원하는 함수들이 등록되어 있는 새로운 인터페이스를 작성한 뒤, window 인터페이스에 대해서 이 커스텀 인터페이스를 쓸 것이다! 하고 선언하는 방식이다.
export interface HybridWindow extends Window {
handleAndroidBackButtonPress: () => void;
}
declare let window : HybridWindow;
window.handleAndroidBackButtonPress = () => {
history.back();
...
}
두번째는 typescript 의 type assertion 기능을 이용하는 방식이다.
(window as any).handleAndoridBackButtonPress = () =(
function(){...}
)
다음 방식은 Window
에서 스크립트 간 통신을 위해 지원하는 postMessage()
를 이용하는 것이다.
postMessage()
는 window 객체 간의 cross-origin communication을 가능하게 해주는 메서드로써, 원래 서로 다른 페이지 상의 스크립트들은 same-origin policy에 해당하는 스크립트들끼리만 소통이 가능하지만, postMessage()
를 이용하면 이 제한을 비켜갈 수 있다.
하지만 제한을 비켜감으로서 보안에 취약해질 수 있으므로, MDN 글을 읽어보면 알겠지만 항상 origin과 source를 명시하고, 체크해야한다!!!
targetWindow.postMessage(message, targetOrigin, [transfer] )
targetWindow.postMessage("app_quit");
*
를 사용가능하지만 보안상 항상 명시해주는 것을 MDN에서 권장하고 있다! ( ex. 비밀번호 전송에 쓰일 경우 인터셉트 당할수있음 )window.addEventListener("message", (event) => {
if(event.origin !== "http://example.org:8080")
return;
}, false);
이 이벤트를 구성하는 요소들은 다음과 같다.
항상 메시지를 수신할 때 sender의 identity를 체크할 것 ( origin 체크하기 )
window.onMessage
를 이용해서 받아올 수도 있다.
여기에서 말하는 origin의 경우 서로 다른 웹사이트 간 통신할 때 중요한 부분이다. (ex. 특정 사이트 내부에 iframe으로 들어간 사이트)
만약 하이브리드 앱 등에서 사용한다면.. 그래도 조심해야 할 것 같긴 하다. 관련해서 어떤 postMessage를 지원하는지는 알 수 없지만 웹 특성상 아무나 하이브리드 앱을 통해서 악의적인 postMessage 통신이 가능하기 때문에!
Window.postMessage() - Web APIs | MDN
How to add new property to window object in typescript? | Cloudhadoop