posted by 네코냥이 2013. 3. 18. 10:36

원문출처: http://shanedotcom.blog.me/70142923979



사이트 개발에 있어서 로그아웃 과정을 세션이나 기타 쿠키를 이용하지 않고 처리해야 할 때 어떤 방법을 사용하면 좋을까.

우선 가장 쉽게 생각할 수 있는 것은 로그아웃 버튼을 만들고 사용자가 그 버튼을 눌렀을 때 로그아웃 처리를 하는 방식이 있을 수 있겠다. 그런데 모든 사용자가 버튼을 눌러 로그아웃 한다고 장담할 수도 없을 뿐더러 기타 여러가지 이유로 인터넷 창이 닫혔을 때는 

서버에 로그아웃 했다는 기록이 남지 않게 된다. 서버는 여전히 로그인 상태로 인지하게 될 것이다.

 

사용자의 로그인 로그아웃 기록이 별로 중요하지 않거나 또는 중복 로그인 자체에 대한 별도의 제한을 주지 않을거라면

사실 로그아웃 처리는 그다지 큰 문제가 아닐지도 모른다. 그러나 쇼핑몰과 같이 사용자의 구매 정보에 대한 신뢰있는 저장 및 처리가

필요한 사이트라면 로그아웃 처리 자체 만으로도 사이트 개발 시에 대단히 신중하게 구현해야 할 부분이다.

 

여기서는 쇼핑몰과 같은 민감한 사이트는 아닐지라도 여러 이유로 인하여 로그아웃 처리를 순수하게 자바스크립트 만으로

처리해야 한다고 생각해 보자. 로그아웃 처리라고는 해도 실제로 구현해 보고자 하는 것은 사용자가 인터넷 창을 그냥 닫았을 경우

그 이벤트를 받아서 로그아웃 처리 함수로 보내는 정도면 충분할 것이다. 그러면 어떤 식으로 처리하면 좋을까.

 

그러기 위해서는 일단 자바스크립트에서 인터넷 창을 닫았을 때 감지할 수 있는 이벤트가 있는지 생각해 보자.

 

1. onbeforeunload

onbeforeunload 이벤트는 도큐먼트가 닫히기 전에 처리할 함수를 지정할 수 있다.

 

<script language="javascript">

function closePage(){

// 창이 닫혔을 때 처리할 함수

}

</script>

 

<BODY onbeforeunload="closePage()">

 

위와 같은 방식으로 창이 닫힐 때, 정확하게 말하면 페이지가 언로드 될 때 closePage() 라는 자바스크립트 함수가 실행된다.

 

 

 

2. 새로고침( reload )의 문제

안타깝게도 로그아웃 처리와 관련하여 onbeforeunload 이벤트를 적용하는데는 아주 큰 단점이 있다.

바로 새로고침의 문제이다. onbeforeunload에 대해서 정확하게 말했듯이 이는 페이지 닫힐 때의 이벤트가 아니라

페이지가 언로드 될 때 일어나는 이벤트 이다. 인터넷 창을 닫을 때 외에도 페이지가 언로드 되는 경우는 아주 많다.

쉽게 생각해 볼 수 있는 것은 새로고침의 경우. 새로고침은 페이지를 언로드 했다가 다시 로드 과정( reload )이기 때문에

언로드 될 때 바로 closePage() 함수가 수행되어 버리고, 이 부분을 로그아웃 처리로 이용한다면 사용자는 새로고침 만으로도

로그아웃 되어 버리는 불상사가 발생하게 된다.

 

새로고침과 페이지를 닫은 경우를 구별할 수 있는 팁이 있다면 좋겠지만 아직까지는 그에 대해 뚜렷한 해결책은 없다.

( 이벤트 좌표로 처리할 수도 있겠으나, 이 경우에도 완전하지 않다. 이에 대해서는 나중에 설명하겠다. )

 

그렇다면 현실적으로 할 수 있는 방법이란 결국 새로고침 이벤트를 막는 것 뿐이다.

새로고침 이벤트는 키보드의 F5 외에도 마우스오른쪽버튼을 눌렀을 때 나타나는 팝업 메뉴라든가 기타 Ctrl+R, Ctrl+L 등등을

모두 막아야 한다.

 

이와 관련해서는 다음과 같이 간단히 자바스크립트로 처리할 수 있다. 

( 키 코드 값과 관련해서는 검색해보기 바란다. ) 

 

<script language="javascript"> 

document.onkeydown = function() { 

// 새로고침 방지 ( Ctrl+R, Ctrl+N, F5 )
if ( event.ctrlKey == true && ( event.keyCode == 78 || event.keyCode == 82 ) || event.keyCode == 116) {

event.keyCode = 0;
event.cancelBubble = true;
event.returnValue = false;

}

 

// 윈도우 창이 닫힐 경우
if (event.keyCode == 505) { 
    alert(document.body.onBeforeUnload);
}

 </script>

 

3. 기타 문제

그렇다면 이제 모두 해결된 것일까?

 

안타깝게도 경우에 따라 여전히 문제가 되는 경우가 있다.

가장 먼저 떠오르는 것은 

 

1) 사용자가 새로고침을 하지 않았는데로 새로고침 현상이 일어나는 경우

2) 사용자가 Alt+F4 를 눌러 강제로 창을 닫는 경우 

 

2) 의 경우에는 2. 새로고침의 문제와 마찬가지로 F4 에 대한 키 이벤트를 방지하는 것이다.

 

<script language="javascript">  

// 창 닫기( Alt+F4 ) 방지 
if ( event.keyCode == 115) { // F4 눌렀을 시
   // 로그아웃 처리
}

</script>

 

1) 의 경우는 어떤 경우에 일어날까?

 

사용자가 페이지에서 특정 메뉴를 클릭했는데 그 메뉴가 자바스크립트 상에서 페이지가 리로드를 일으킨다거나

또는 ActiveX 등에서 제공한 자바스크립트 메소드가 페이지 리로드를 수반하는 경우 등이다.

 

그걸 인터넷 창을 닫는 이벤트와 구별하는 방법은 이벤트 발생 좌표를 이용하는 방법이 있다.

 

즉, 사용자가 페이지 내의 어떤 메뉴를 수행한다는 것은 클릭했을 시점의 마우스 이벤트가 페이지 영역 내 일 것이므로

X, Y 좌표가 모두 + 값을 갖는다.

 

1. 에서 지정했던 BODY 부분을 보면

<BODY onbeforeunload="closePage()"> 

을 볼 수 있는데 여기에서 closePage( event ) 라고 하면 이벤트 좌표를 변수로 closePage 함수에 넘길 수 있다. 

  

이벤트 좌표는 ( event.X, event.Y ) 와 같이 받을 수 있는데 페이지 영역의 좌측 상단 끝을 기점으로

오른쪽으로 갈 수록 event.X 값이 커지며, 아래로 내려 갈 수록 event.Y 값이 커진다.

 

그렇다면 페이지 영역 밖이라면? 쉽게 말해 인터넷 창 오른쪽 상단 끝에 있는 X 버튼이라면 어떤 좌표 값을 가질까?

 

우선 event.X 값은 사용자의 모니터 해상도 가로값에 따라 다르며, 또한 인터넷 창을 작게 축소했느냐 전체화면이냐에 따라서도 다르다. 그러나 페이지 영역 내이든 외에든 어떤 경우에도 event.X 값은 항상 + 값을 갖게 된다.

 

그러나 event.Y 값은 사용자의 모니터의 해상도나 인터넷 창의 크기와도 상관없이 모두 - 값을 갖게 된다.

페이지 영역 밖의 인터넷 창이라면 event.Y 값은 - 를 갖게 되므로 이것으로 사용자가 인터넷 창을 닫았다고 인식하면 된다.

 

그 구현은 다음과 같다.

 

<script language="javascript">

// 윈도우 창을 닫을 때 로그아웃 처리

function closePage( event ){
     if( event.clientY < 0 ){
     // 로그아웃 처리
     }

}

</script>

 

<BODY onbeforeunload="closeIt(event)">

 

 

 

 

 

이로서 제한적이나마 사용자가 인터넷 창을 닫았을 경우에 감지해서 특정 기능( 로그아웃 처리 같은 )을 부여할 수 있다. 

 

전체적인 소스 코드는 아래와 같다.  

 

 

 

 

 

 

 

--- 소스코드 --- 

// 자바스크립트를 이용한 로그아웃 처리 ( 인터넷 창을 닫았을 경우 ) 

<script language="javascript">
// 윈도우 창을 닫을 때 로그아웃 처리
   function closePage( event ){
      if( event.clientY < 0 ){
         // 로그아웃 처리
      }

   }

 
   document.onkeydown = function() {
       // 새로고침 방지 ( Ctrl+R, Ctrl+N, F5 )
       if ( event.ctrlKey == true && ( event.keyCode == 78 || event.keyCode == 82 ) || event.keyCode == 116) {
            event.keyCode = 0;
            event.cancelBubble = true;
            event.returnValue = false;
       }

 

       // 창 닫기( Alt+F4 ) 방지 
       if ( event.keyCode == 115) { // F4 눌렀을 시
         // 로그아웃 처리

       }

 

       // 윈도우 창이 닫힐 경우
       if (event.keyCode == 505) { 
           alert(document.body.onBeforeUnload);
      }
}
</script>

 

 

<BODY onbeforeunload="closePage(event)" oncontextmenu="return false">

// oncontextmenu="return false" : 마우스 오른쪽 버튼 막기 ( 팝업메뉴 보기 방지 )





----------------------------------------------------------------------------------

----------------------------------------------------------------------------------


[동적할당]


window.onbeforeunload = 함수명 ;


window.onbeforeunload = function() {


// 내용기술

}