CI 묻고 답하기

제목 Ajax 세션 문제??
글쓴이 방문넷 작성시각 2013/09/28 14:01:05
댓글 : 4 추천 : 0 스크랩 : 1 조회수 : 12885   RSS
 -------이고잉님의 팁 인용 ----------
ajax 통신을 할 때마디 로그인이 풀리는 문제가 있었습니다. 
이 문제의 원인은 이렇습니다. 
 
1. CI는 5분에 한번씩 session id를 교체합니다. 세션 하이제킹을 방지하기 위해서 입니다. 
2. ajax 콜이 1초에 한번씩 일어납니다.
 
1번과 2번의 조건이 동시에 만족되는 상황에서 먼저 먼저 호출된 ajax 통신이 끝나기 전에 후행 ajax 호출이 시작되면 후행 ajax는 존재하지 않는 세션 아이디 값을 데이터베이스 등에서 조회하게 됩니다. 
 
이 문제를 해결하기 위해서 ajax 호출의 경우 세션 업데이트가 일어나지 않도록 처리했습니다. 
어차피 세션 업데이트는 페이지 전환 시에 일어나는 빈도로도 충분히 커버가 가능하다고 생각됩니다. 
 
찾아보니 아래와 같은 논의가 이미 있었네요. 여기의 코드를 사용했습니다. 
http://ellislab.com/forums/viewthread/203821/
------------------------------------------------------------------------------------------------

제가 이해를 잘 못해서 질문좀 해볼려고 합니다.

로그인후에(Tank_auth사용) ajax가 빈번히 많이 발생되는 페이지를 만들었습니다.

Ajax로 컨트롤러 호출 -> 컨트롤러에서 모델호출 -> 모델에서 데이터 리턴 ->컨트롤러에서 JSON형식으로 리턴 -> AJAX신호 받음

이렇게 로직이 흘러가는데 클라이언트가 30~40개 정도 붙어있으면 간헐적으로 세션이 죽어버리는 현상이 발생되더라구요

그걸 해결코자 팁 게시판에 이고잉님께서 링크를 하나 제시 해주셨는데 영어 울렁증이 있어서 그런지 코드가 정확히 어느싯점에 쓰이는가를 잘 몰르겠습니다(제가 이해를 못하는게 맞겠네요.. 아직 코드 제대로 보는 능력이 없나봅니다)

이 코드가 어느 싯점에 쓰이는지좀 알려주시면 감사하겠습니다.
태그 ajax,세션
 다음글 codeiginter - wordpress 연동?? (1)
 이전글 또 문제입니다 ㅠㅠ 글쓰기할때 숫자 영어는 넣어지는데.... (2)

댓글

letsgolee / 2013/09/28 17:27:06 / 추천 0
 제가 이해하는게 맞다면 CI는 세션 하이제킹을 막기위해 5분마다 세션 아이드를 교체합니다. 이것은 ajax접속시에도 동일하게 적용됩니다.

그런데 ajax 여러 접속들이 일어나는 중에 그중 어떤 접속이  sess_update를 실행해버리면 세션 아이디가 교체된 것이므로 다른 접속들은 그냥 죽어버립니다. 따라서 이것을 막기위해 ajax접속으로 판단되면 세션 아이디를 교체하는 sess_update를 실행하지 않도록 해야 하겠죠.

따라서 다음의 소스를 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 */ 
소스를 보면 ajax_request가 아닌 경우에만 sess_update()를 실행하게 되어 있습니다.

글을 계속 읽어보니 다음도 확인해보아야 합니다: 데이터베이스의 session 테이블의 user_agent 필드의 varchar값이 120인지 체크해야 합니다. 일반적으로 세션 테이블 이름은 ci_sessions이므로 여기의 user_agent 필드를 확인하면 되겠습니다. 이유는 나와 있지 않지만 ajax접속시 user_agent값이 일반 접속보다 조금 더 길기 때문이 아닐까 짐작해봅니다.
방문넷 / 2013/09/28 17:46:59 / 추천 0
 letgolee // 감사합니다. 감이 확 왔네요. 지금 이걸 적용하기전에 메뉴엘에서 세션관련을 다시한번 파고있습니다.

왜 세션이 죽는지에 대해서 정확하게 감이 와버려서 지금 기분이 업 됬네요 ^^ 다시한번 감사합니다.

아 그리고 부연설명해주신거 덕분에 코딩 막혔던 부분까지 해소 됬습니다 감사합니다!!!
율마 / 2013/12/12 12:29:45 / 추천 0
 같은 문제로 고민중이였는데  ~ 감사합니다!!
강동원 / 2017/02/01 16:20:25 / 추천 0
저도 같은 문제로 고민 중이였는데 감사드립니다.