본문 바로가기
개발하는 '정'/JS

[javascript] KCP 본인인증 모바일 window.opener 작동 문제 해결

by 주앤정_블로그 2021. 6. 3.

[javascript] KCP 본인인증 모바일 window.opener 작동 문제 해결

자바스크립트 KCP 본인인증 모바일 window.opener 작동 문제

 

개발 환경 : PHP + 그누보드 

테스트 환경 : IOS 사파리, 크롬

 

문제점 : 모바일 브라우저에서 그누보드 본인확인 플러그인 kcpcert의 window.opener, window.parent 가 작동 안 됨

(  window.parent.$ is not a function .. 오류 발생 )

 

해결 방법 : window.opener, window.parent.$(~) 를 opener.document.getElementById(~) 로 변경

( rel noopener를 적용해야한다는 글도 봤는데 이번 경우에는 rel로 해결되지 않았다.. )

 

변경 파일

: /mobile/skin/member/basic/register_form.skin.php (회원가입 / 회원정보 수정 페이지)

  /plugin/kcpcert/kcpcert_form.php

  /plugin/kcpcert/kcpcert_result.php

 

변경 내용

1-1) register_form.skin.php 변경 전 

<input type="hidden" name="cert_type" value="<?php echo $member['mb_certify']; ?>">
<input type="hidden" name="cert_no" value="">
<input type="hidden" name="veri_up_hash" value="" >
<input type="text" name="mb_name" value="<?php echo $member['mb_name'] ?>">
<input type="text" name="mb_hp" value="<?php echo $member['mb_hp'] ?>" > 

 

1-2) register_form.skin.php 변경 후

: id 추가 

<input type="hidden" name="cert_type" id="cert_type" value="<?php echo $member['mb_certify']; ?>">
<input type="hidden" name="cert_no" id="cert_no" value="">
<input type="hidden" name="veri_up_hash" id="veri_up_hash" value="">
<input type="text" name="mb_name" id="reg_mb_name" value="<?php echo $member['mb_name'] ?>">
<input type="text" name="mb_hp" id="reg_mb_hp" value="<?php echo $member['mb_hp'] ?>" > 

 

2-1) kcpcert_form.php 변경 전

<script>
window.onload = function() {
    cert_page();
}

// 인증 요청 시 호출 함수
function cert_page()
{
    var frm = document.form_auth;

    if ( ( frm.req_tx.value == "auth" || frm.req_tx.value == "otp_auth" ) )
    {
    	...생략
    }

    else if ( frm.req_tx.value == "cert" )
    {
        if( ( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 ) ) // 스마트폰인 경우
        {
            window.parent.$("input[name=veri_up_hash]").val(frm.up_hash.value); // up_hash 데이터 검증을 위한 필드
            self.name="auth_popup";
        }
        else // 스마트폰 아닐때
        {
            window.opener.$("input[name=veri_up_hash]").val(frm.up_hash.value); // up_hash 데이터 검증을 위한 필드
            frm.target = "auth_popup";
        }

        frm.action="<?php echo $cert_url; ?>";
        frm.submit();
    }
}
</script>

 

2-2) kcpcert_form.php 변경 후

 : window.parent -> opener.~ 로 변경

<script>
window.onload = function() {
    cert_page();
}

// 인증 요청 시 호출 함수
function cert_page()
{
    var frm = document.form_auth;

    if ( ( frm.req_tx.value == "auth" || frm.req_tx.value == "otp_auth" ) )
    {
    	...생략
    }

    else if ( frm.req_tx.value == "cert" )
    {
        if( ( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 ) ) // 스마트폰인 경우
        {
            //window.parent.$("input[name=veri_up_hash]").val(frm.up_hash.value); // up_hash 데이터 검증을 위한 필드
            opener.document.getElementById("veri_up_hash").value=frm.up_hash.value; 
            self.name="auth_popup";
        }
        else // 스마트폰 아닐때
        {
            window.opener.$("input[name=veri_up_hash]").val(frm.up_hash.value); // up_hash 데이터 검증을 위한 필드
            frm.target = "auth_popup";
        }

        frm.action="<?php echo $cert_url; ?>";
        frm.submit();
    }
}
</script>

 

3-1) kcpcert_result.php 변경 전

<script>
$(function() {
    var $opener;
    var is_mobile = false;

    if( ( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 ) ) { // 스마트폰인 경우
        $opener = window.parent;
        is_mobile = true;
    } else {
        $opener = window.opener;
    }

    // up_hash 검증
    if( document.form_auth.up_hash.value != $opener.$("input[name=veri_up_hash]").val() ) {
        alert("up_hash 변조 위험있음");
    }

    // 인증정보
    $opener.$("input[name=cert_type]").val("<?php echo $cert_type; ?>");
    $opener.$("input[name=mb_name]").val("<?php echo $user_name; ?>").attr("readonly", true);
    $opener.$("input[name=mb_hp]").val("<?php echo $phone_no; ?>").attr("readonly", true);
    $opener.$("input[name=cert_no]").val("<?php echo $md5_cert_no; ?>");

    if(is_mobile) {
        $opener.$("#cert_info").css("display", "");
        $opener.$("#kcp_cert" ).css("display", "none");
    }

    alert("본인의 휴대폰번호로 확인 되었습니다.");

    window.close();
});
</script>

 

3-2) kcpcert_result.php 변경 후

 : window.parent -> opener.~ 로 변경

<script>
$(function() {
    var $opener;
    var is_mobile = false;

    if( ( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 ) ) { // 스마트폰인 경우
        $opener = window.parent;
        is_mobile = true;
		// up_hash 검증
		if( document.form_auth.up_hash.value != opener.document.getElementById("veri_up_hash").value ) {
			alert("up_hash 변조 위험있음");
		}

		// 인증정보
		opener.document.getElementById("cert_type").value = "<?php echo $cert_type; ?>";
		opener.document.getElementById("mb_name").value = "<?php echo $user_name; ?>";
		opener.document.getElementById("mb_hp").value = "<?php echo $phone_no; ?>";
		opener.document.getElementById("cert_no").value = "<?php echo $md5_cert_no; ?>";
    } else {
        $opener = window.opener;
		// up_hash 검증
		if( document.form_auth.up_hash.value != $opener.$("input[name=veri_up_hash]").val() ) {
			alert("up_hash 변조 위험있음");
		}
		
		$opener.$("input[name=cert_type]").val("<?php echo $cert_type; ?>");
		$opener.$("input[name=mb_name]").val("<?php echo $user_name; ?>").attr("readonly", true);
		$opener.$("input[name=mb_hp]").val("<?php echo $phone_no; ?>").attr("readonly", true);
		$opener.$("input[name=cert_no]").val("<?php echo $md5_cert_no; ?>");
    }
    
    if(is_mobile) {
        $opener.$("#cert_info").css("display", "");
        $opener.$("#kcp_cert" ).css("display", "none");
    }

    alert("본인의 휴대폰번호로 확인 되었습니다.");

    window.close();
});
</script>

 

if(is_mobile) { .. } 안의 $opener 도 필요한경우 변경해주면 된다..

 

 

+ 추가

위의 내용 외에 본인인증 창 자체를 팝업이 아니라 내부로 붙이는게 더 좋을 것 같다. ( 팝업창은 앱 적용 시 문제 생길 수 있음 )

 

 /js/certify.js 변경 전

// 본인확인 인증창 호출
function certify_win_open(type, url)
{
    if(type == 'kcb-ipin')
    {
        var popupWindow = window.open( url, "kcbPop", "left=200, top=100, status=0, width=450, height=550" );
        popupWindow.focus();
    }
    else if(type == 'kcb-hp')
    {
        var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=430, height=590, scrollbar=yes" );
        popupWindow.focus();
    }
    else if(type == 'kcp-hp')
    {
        var return_gubun;
        var width  = 410;
        var height = 500;

        var leftpos = screen.width  / 2 - ( width  / 2 );
        var toppos  = screen.height / 2 - ( height / 2 );

        var winopts  = "width=" + width   + ", height=" + height + ", toolbar=no,status=no,statusbar=no,menubar=no,scrollbars=no,resizable=no";
        var position = ",left=" + leftpos + ", top="    + toppos;
        var AUTH_POP = window.open(url,'auth_popup', winopts + position);
    }
    else if(type == 'lg-hp')
    {
        var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=400, height=400, scrollbar=yes" );
        popupWindow.focus();
    }
}

 

/js/certify.js 변경 후

function certify_win_open2(type, url,event)
{
    if(type == 'kcb-ipin')
    {
        var popupWindow = window.open( url, "kcbPop", "left=200, top=100, status=0, width=450, height=550" );
        popupWindow.focus();
    }
    else if(type == 'kcb-hp')
    {
        var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=430, height=590, scrollbar=yes" );
        popupWindow.focus();
    }
    else if(type == 'kcp-hp')
    {

		if( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 )
        {

		 var $frm = $(event.target.form);
			
            if($("#kcp_cert").length < 1) {
                $frm.wrap('<div id="cert_info"></div>');

                $("#cert_info").append('<form name="form_temp" method="post">');
            } else {
                $("#kcp_cert").remove();
            }

            $("#cert_info")
                .after('<iframe id="kcp_cert" name="kcp_cert" width="100%" height="700" frameborder="0" scrolling="no" style="display:none"></iframe>');

            var temp_form = document.form_temp;
            temp_form.target = "kcp_cert";
            temp_form.action = url;
            document.getElementById( "cert_info" ).style.display = "none";
            document.getElementById( "kcp_cert"  ).style.display = "";

            temp_form.submit();

		}
        else
        {
            var return_gubun;
			var width  = 410;
			var height = 500;

			var leftpos = screen.width  / 2 - ( width  / 2 );
			var toppos  = screen.height / 2 - ( height / 2 );

			var winopts  = "width=" + width   + ", height=" + height + ", toolbar=no,status=no,statusbar=no,menubar=no,scrollbars=no,resizable=no";
			var position = ",left=" + leftpos + ", top="    + toppos;
			var AUTH_POP = window.open(url,'auth_popup', winopts + position);
        }
    }
    else if(type == 'lg-hp')
    {
        var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=400, height=400, scrollbar=yes" );
        popupWindow.focus();
    }
}

 

 

반응형

댓글