본문 바로가기
그누보드,영카트

그누보드 중복로그인 차단

by 씨엔아이소프트 2024. 9. 27.
반응형

1. 데이터베이스에 세션 필드 추가

먼저, g5_member 테이블에 세션 정보를 저장할 수 있는 필드 mb_session_id를 추가해야 합니다.

 
ALTER TABLE g5_member ADD mb_session_id VARCHAR(255) DEFAULT NULL;​

2. 로그인 시 세션 값 생성 및 저장

사용자가 로그인할 때 고유한 세션 값을 생성한 후, 그 값을 g5_member 테이블의 mb_session_id 필드에 저장합니다. 또한, 이 세션 값은 PHP 세션에도 저장하여 추후 확인할 수 있도록 합니다.

/bbs/login_check.php 파일에 로그인 성공 후 세션 값을 생성하고 저장하는 코드를 추가합니다.

 
// 중복 로그인 체크를 위한 세션 값 생성
$login_session = getloginsession(12); // 12자리의 랜덤 세션 값 생성
set_session('login_session', $login_session); // PHP 세션에 저장

// 로그인한 사용자의 세션 값을 데이터베이스에 저장
$sql = "UPDATE {$g5['member_table']} SET mb_session_id = '$login_session' WHERE mb_id = '{$mb['mb_id']}'";
sql_query($sql);

 


3. 중복 로그인 확인 로직 추가

다음으로, 사용자 활동 중 중복 로그인을 확인하는 코드를 추가해야 합니다. 이를 위해 모든 페이지에 삽입되는 헤더 또는 푸터 파일에 AJAX 요청을 추가하여 일정 주기로 사용자의 세션 값을 확인합니다.

헤더/푸터 파일 수정:

헤더나 푸터에 AJAX 요청을 추가하여 7초마다 /bbs/ip_check.php로 세션 체크를 수행하는 자바스크립트를 삽입합니다.

 
<?php if($member['mb_id'] != "") { ?>
<script type="text/javascript">
    var get_con_suer = function() {
        $.ajax({
            type: "POST",
            url: "/bbs/ip_check.php",
            dataType: "html",
            success: function(responseText) {
                if (responseText == 'login_fail') {
                    alert('로그인 후 이용해주세요.');
                    location.href = "/bbs/login.php";
                }
                if (responseText == 'ip_fail') {
                    alert('중복 로그인 되어 로그아웃 되었습니다.');
                    location.href = "/bbs/login.php?ipcheck=fail";
                }
                setTimeout(get_con_suer, 7000); // 7초 후 다시 체크
            },
            error: function(responseText) {
                return false;
            }
        });
    };

    get_con_suer();
</script>
<?php } ?>

4. 세션 체크 파일 구현 (ip_check.php)

중복 로그인을 확인하는 PHP 파일을 생성합니다. 이 파일에서는 현재 세션 값이 데이터베이스에 저장된 세션 값과 일치하는지 확인하고, 일치하지 않을 경우 중복 로그인으로 간주하여 사용자를 로그아웃 시킵니다.

/bbs/ip_check.php:

 
<?php
include_once('./_common.php');

// 로그인하지 않은 경우 처리
if($member['mb_id'] == "") {
    echo 'login_fail';
    exit;
}

// 어드민 계정은 중복 로그인 체크 제외
if($member['mb_id'] == "admin") {
    echo 'ip_success';
    exit;
}

// 로그인된 사용자의 세션 값 확인
if(!empty($member['mb_id'])) {
    // 현재 로그인된 사용자의 세션 값을 조회
    $sql = "SELECT mb_session_id FROM {$g5['member_table']} WHERE mb_id = '".$member['mb_id']."'";
    $mbl = sql_fetch($sql);

    $db_session_id = $mbl['mb_session_id']; // DB에 저장된 세션 값

    // PHP 세션에 저장된 값과 DB에 저장된 값이 일치하는지 확인
    if(get_session('login_session') == $db_session_id) {
        echo 'ip_success';
    } else {
        // 세션 불일치: 중복 로그인으로 간주하여 세션 종료
        session_unset(); // 모든 세션 변수 삭제
        session_destroy(); // 세션 종료
        setcookie(session_name(), '', time() - 3600); // 세션 쿠키 삭제

        echo 'ip_fail';
    }
    exit;
}
?>

5. 랜덤 세션 값 생성 함수 (common.lib.php)

랜덤한 세션 값을 생성하는 함수를 lib/common.lib.php에 추가합니다. 보안을 위해 랜덤 문자열을 생성하는 방법을 좀 더 강화할 수 있습니다.

/lib/common.lib.php 하단에 추가:

 
function getloginsession($codeLength) {
    // PHP의 random_bytes를 사용하여 보안성이 높은 랜덤 값 생성
    return bin2hex(random_bytes($codeLength / 2));
}

6. 로그아웃 시 세션 값 초기화

로그아웃할 때는 g5_member 테이블의 mb_session_id 값을 초기화해야 합니다. /bbs/logout.php에서 사용자가 로그아웃할 때 세션 값을 지우는 로직을 추가합니다.

/bbs/logout.php 수정:

 
// 로그아웃 시 세션 값 초기화
sql_query("UPDATE {$g5['member_table']} SET mb_session_id = NULL WHERE mb_id = '{$member['mb_id']}'");

 

반응형

댓글