그누보드 자동 로그아웃 질문 드립니다.
본문
common.php에서
ini_set("session.cache_expire", 1); // 세션 캐쉬 보관시간 (분)
ini_set("session.gc_maxlifetime", 60); // session data의 garbage collection 존재 기간을 지정 (초)
ini_set("session.gc_probability", 1); // session.gc_probability는 session.gc_divisor와 연계하여 gc(쓰레기 수거) 루틴의 시작 확률을 관리합니다. 기본값은 1입니다. 자세한 내용은 session.gc_divisor를 참고하십시오.
ini_set("session.gc_divisor", 1); // session.gc_divisor는 session.gc_probability와 결합하여 각 세션 초기화 시에 gc(쓰레기 수거) 프로세스를 시작할 확률을 정의합니다. 확률은 gc_probability/gc_divisor를 사용하여 계산합니다. 즉, 1/100은 각 요청시에 GC 프로세스를 시작할 확률이 1%입니다. session.gc_divisor의 기본값은 100입니다.
이렇게 바꾸면 자동로그아웃이 되긴합니다 근데 새로고침을 해야만 자동로그아웃이 되더라구요
구현하고자 하는건 세션이 로그아웃될시 alert('장시간 입력이 없어 자동로그아웃 되었습니다.') 이런 text를 띄우고 자동 로그아웃을 하고자 합니다.
if ($is_member) { // 로그인한 사용자만 적용
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $session_timeout)) {
// 로그아웃 후 이동할 로그인 URL 설정
// 세션 만료 처리 (자동 로그아웃)
session_unset();
session_destroy();
echo "<script>
var sessionTimeout = " . ($session_timeout * 1000) . "; // 밀리초 변환
setTimeout(function() {
alert('세션이 만료되었습니다. 다시 로그인해 주세요.'); // 작은따옴표 사용
window.location.href = '" . $login_url . "'; // 작은따옴표 사용
}, sessionTimeout);
</script>";
exit;
}
$_SESSION['last_activity'] = time(); // 마지막 활동 시간 갱신
// ** 클라이언트에서도 자동 로그아웃 감지 **
echo "<script>
var sessionTimeout = " . ($session_timeout * 1000) . "; // 밀리초 변환
console.log(sessionTimeout);
function startSessionTimer() {
window.sessionTimer = setTimeout(function() {
alert('세션이 만료되었습니다. 다시 로그인해 주세요.');
window.location.href = '" . $login_url . "';
}, sessionTimeout);
}
</script>";
common.php에 이렇게해도 자동로그아웃이 안됩니다 뭐가 문제인지 모르겠습니다 부탁드립니다.
답변 2
<?php
session_start(); // 세션을 시작 (필수)
// 세션 유지 시간 (초 단위)
$session_timeout = 1800; // 예: 30분
// 로그인 URL 설정 (로그아웃 후 이동할 페이지)
$login_url = "/login.php"; // 로그인 페이지 URL
// 로그인한 사용자만 체크
if ($is_member) {
// 현재 시간
$current_time = time();
// 마지막 활동 시간이 설정되어 있다면 타임아웃 체크
if (isset($_SESSION['last_activity'])) {
$time_diff = $current_time - $_SESSION['last_activity']; // 마지막 활동과 현재 시간 차이
if ($time_diff > $session_timeout) {
// 세션 만료 처리 (자동 로그아웃)
session_unset();
session_destroy();
// JavaScript를 사용하여 자동 리다이렉트
echo "<script>
alert('세션이 만료되었습니다. 다시 로그인해 주세요.');
window.location.href = '{$login_url}';
</script>";
exit; // PHP 코드 실행 중지
}
}
// 마지막 활동 시간 갱신
$_SESSION['last_activity'] = $current_time;
}
// 클라이언트 측에서도 자동 로그아웃 감지
echo "<script>
var sessionTimeout = " . ($session_timeout * 1000) . "; // 밀리초 변환
console.log('Session timeout set for: ' + (sessionTimeout / 1000) + ' seconds');
function startSessionTimer() {
clearTimeout(window.sessionTimer); // 기존 타이머 제거
window.sessionTimer = setTimeout(function() {
alert('세션이 만료되었습니다. 다시 로그인해 주세요.');
window.location.href = '{$login_url}';
}, sessionTimeout);
}
// 페이지 로드 시 타이머 시작
startSessionTimer();
// 사용자가 활동할 때마다 타이머 리셋
document.addEventListener('mousemove', startSessionTimer);
document.addEventListener('keypress', startSessionTimer);
</script>";
?>
문제 분석
자동 로그아웃이 정상적으로 동작하지 않는 이유는 다음과 같을 수 있습니다.
-
세션 갱신 문제
$_SESSION['last_activity']
가 갱신되지 않아서 자동 로그아웃이 실행되지 않을 가능성session_start()
가 호출되지 않아서$_SESSION
이 제대로 작동하지 않을 가능성
-
클라이언트 측(브라우저) 타이머 문제
setTimeout()
이 실행되지 않는지 확인 필요 (브라우저 콘솔 오류 확인)- 페이지가 갱신될 때마다
setTimeout()
이 초기화되므로 타이머가 제대로 동작하지 않을 가능성
-
세션 타임아웃 로직 문제
- PHP에서는 서버 측에서 세션이 살아있는지 체크해야 함
- 클라이언트에서만
setTimeout()
을 사용하면 서버가 사용자의 세션을 인식하지 못할 수 있음
당연히 동기식 에서는 페이지 로드 후 모든 결과가 뿌려지고
모든 코드가 종료가 되어도 다른 코드가 없다면 별도 액션을 줄 수 없습니다.
예를들어
철수가 배달음식을 시켰는데 배달이 다되고 문앞에 왔는데도
배달원이나 어플에서 알림이 없다면 철수는 배달이 온지도 모르겠죠.. 음식은 문앞에 있는데도요..
아주 간단하게 해결 가능합니다.
어차피 자동로그아웃이란건 타이머니까.
tail.php 에 적당히 타임아웃 스크립트만 넣으면됩니다.
그러면 페이지를 이동 할때마다 자동 갱신되겠죠?
그리고 페이지를 이동하지 않고 아무런 액션도 하지 않으면 타임아웃 시간은 계속 줄어들테고
바로 /bbs/logout.php 로 이동하여 로그아웃 시켜도되고
아니면 별도 펑션으로 div 등을 띄워서 남은시간이 얼마 안남았음을 카운트다운 해도 됩니다..
자바스크립트 몇줄이면 별도의 세션도 필요없어요...