CI 묻고 답하기

제목 ajax 세션 유지실패에 대해서 질문을 드립니다.
글쓴이 bld 작성시각 2014/08/11 10:52:14
댓글 : 5 추천 : 0 스크랩 : 0 조회수 : 25239   RSS
게시판을 만들면서 댓글 기능을 AJAX를 이용하여 구현을 했는데, 이상하게 자꾸 4~5분 간격으로 세션을 잃게 되어서

검색을 해보니 http://www.codeigniter-kr.org/qna/view/11279/page/1/q/ajax%20%EC%84%B8%EC%85%98에서 저와 유사한 케이스가 있어서 저기에 나와있는 방법대로 application/libraries밑에 MY_Session.php파일을 만들어

/**
 * ------------------------------------------------------------------------
 * CI Session Class Extension for AJAX calls.
 * ------------------------------------------------------------------------
 *
 * ====- Save as application/libraries/MY_Session.php -====
 */

class MY_Session extends CI_Session {

    // --------------------------------------------------------------------

    /**
     * sess_update()
     *
     * Do not update an existing session on ajax or xajax calls
     *
     * @access    public
     * @return    void
     */
    public function sess_update()
    {
        $CI = get_instance();

        if ( ! $CI->input->is_ajax_request())
        {
            parent::sess_update();
        }
    }

}

// ------------------------------------------------------------------------
/* End of file MY_Session.php */
/* Location: ./application/libraries/MY_Session.php */ 
위 코드를 넣어줬지만, 계속 세션을 잃게 됩니다.

 혹시 다른방법이 있거나 조언 부탁드리겠습니다..ㅠㅠ
 다음글 CI 에서 .로 문자열 추가할때 오류가 발생됩니다. (6)
 이전글 CI 이메일 클라스 작동이 에러 나네요...도와 주세요... (2)

댓글

letsgolee / 2014/08/11 17:57:32 / 추천 0
config 상의 세션관련 설정은 어떻게 하셨나요? 세션은 만료 기간이 있어 그 기간에 대한 확인도 해보아야 합니다.
bld / 2014/08/11 19:29:09 / 추천 0
config 상의 세선 관련 설정은 아래와 같습니다.

$config['sess_cookie_name']        = 'ci_session';
$config['sess_expiration']        = 7200;
$config['sess_expire_on_close']    = TRUE;
$config['sess_encrypt_cookie']    = TRUE;
$config['sess_use_database']    = TRUE;
$config['sess_table_name']        = 'ci_sessions';
$config['sess_match_ip']        = TRUE;
$config['sess_match_useragent']    = TRUE;
$config['sess_time_to_update']    = 300;
letsgolee / 2014/08/12 08:24:53 / 추천 0
$config['sess_time_to_update']    = 300;

여기에 답있네요. 300 이니까 5분이 되고 이 기간이 지나면 업데이트가 됩니다. 이 기간을 최대한 길게 해주시면 됩니다.
bld / 2014/08/12 11:49:29 / 추천 0
아하! 답변 감사드립니다!! 해결되었습니다!
tuyitu719 / 2026/03/14 10:58:31 / 추천 0

 

게시하신 증상은 단순히 “세션 만료”라기보다, CodeIgniter의 session_id 재생성과 AJAX 요청이 충돌하는 경우에 더 가깝습니다. 특히 말씀하신 4~5분 간격은 CI의 sess_time_to_update 기본값인 300초와 거의 정확히 맞아떨어집니다. CI는 이 주기마다 session_id를 재생성하는데, AJAX 요청이 겹치면 한 요청은 새 session_id로 갱신되고 다른 요청은 이전 session_id로 접근해서 로그인 정보가 사라진 것처럼 보일 수 있습니다.

즉, MY_Session::sess_update()에서 AJAX일 때만 갱신을 막는 방법이 방향은 맞지만, 동시에 여러 AJAX 요청이 발생하거나, 혹은 일반 요청이 300초 시점을 밟는 경우에는 여전히 같은 문제가 날 수 있습니다. 실제로 CI 포럼에서도 AJAX 동시 요청 때문에 “정확히 5분쯤마다 한 번씩 세션이 풀리는” 사례가 보고되어 있습니다.

실무적으로는 아래처럼 처리하는 경우가 많습니다.

첫째, sess_time_to_update를 기본값 300에서 1800~7200 정도로 늘려서 재생성 빈도를 낮춥니다. 다만 주의할 점은 sess_time_to_updatesess_expiration보다 크게 잡아버리면, 세션 쿠키 갱신이 제때 일어나지 않아 오히려 쿠키가 생성 시점 기준으로 만료될 수 있다는 점입니다. 그래서 보통은 sess_expiration을 더 크게 두고, sess_time_to_update는 그보다 작게 설정합니다.

둘째, 댓글 영역처럼 AJAX가 여러 개 동시에 나가는 구조라면, 요청을 합치거나 순차적으로 보내는 방식으로 바꾸는 것도 효과가 있습니다. 해당 문제는 병렬 요청이 세션 재생성 타이밍과 겹칠 때 특히 잘 나타난다고 정리되어 있습니다.

셋째, MY_Session이 실제로 적용되고 있는지도 확인해보셔야 합니다. AJAX 요청이라고 생각했는데 is_ajax_request()가 false로 잡히면 결국 parent::sess_update()가 실행됩니다. 그래서 로그를 찍어서 해당 메서드가 실제로 타는지 한번 확인하는 게 좋습니다.

답변 예시는 아래처럼 쓰면 자연스럽습니다.


 
 
올려주신 증상은 AJAX 자체라기보다,
CI Session의 session_id 재생성 시점과 AJAX 요청이 겹치면서 발생하는 문제일 가능성이 큽니다.

특히 4~5분 간격으로 세션이 풀린다면
$config['sess_time_to_update'] = 300;
기본값 영향일 가능성이 매우 큽니다.

CI는 일정 시간마다 session_id를 재생성하는데,
댓글처럼 AJAX 요청이 동시에 여러 개 들어오면
한 요청은 새 session_id를 받고,
다른 요청은 이전 session_id로 접근해서
로그인이 풀린 것처럼 보일 수 있습니다.

MY_Session으로 ajax에서 sess_update()를 막는 방법은 맞는 방향이지만,
일반 요청이 갱신 시점을 밟거나
동시 AJAX 요청이 겹치면 여전히 증상이 날 수 있습니다.

보통은 아래처럼 해결합니다.

1. sess_time_to_update 값을 300보다 크게 조정
예: 1800 또는 3600

2. sess_expiration은 sess_time_to_update보다 더 크게 설정

3. 동시에 여러 AJAX 요청이 나가지 않도록
가능하면 요청을 합치거나 순차 호출로 변경

4. MY_Session이 실제 적용되는지 로그로 확인

즉, 지금은 세션 만료라기보다
세션 재생성 타이밍 충돌 문제로 보입니다.