Extra Form
PHP PHP 7.0
CMS XpressEngine

제작자분께서는 그럴리가 없다고 하셨지만 저희 사이트 환경에서는 오류가 발생합니다.

 

1시간 단위로 갱신하게 해 놓았을때 로그인한 회원이 활동중에 해당 애드온에 의해 갱신이 될 때 

프로필이미지와 서명을 가져오지 못하는 상황이 됩니다.

 

이때 로그아웃 후 다시 로그인을 하면 다시 제대로된 정보를 가져올 수 있게 됩니다.

 

각종 스킨등에서 프로필이미지와 서명을 가져오는 것은 모두 비슷한 방식을 사용할 것 입니다.

 

 

로그인이 아니면 리턴시키는 코드

로그인변수 담기

갱신시간이 안되었으면 리턴시키는 코드

$args = new stdClass;
$args->member_srl = $logged_info->member_srl;
executeQuery('member.updateLastLogin', $args);

$oMemberController = getController('member');
$oMemberController->_clearMemberCache($logged_info->member_srl);

 

 

현재 저희는 이 문제 때문에 애드온 사용을 하지 못하고 있는데요. 이문제가 해결이 된다면 자동로그인 사용자가 많아 다시 사이트에서 사용하고 싶습니다.

 

 

11,12 라인의 

$oMemberController = getController('member');
$oMemberController->_clearMemberCache($logged_info->member_srl);

 

부분을 제거해도 로그인시간 갱신에 문제가 없을지도 궁금합니다.

 

 

*라이센스와 별개로 포인트가 무료가 아닌 자료라 코드의 일부만 게시하고 일부는 설명으로 대체했습니다.

 

  • profile

    딱 저렇게 캐시를 비우는 코드뿐인데도 프로필이미지, 서명 등 일부 회원정보가 증발한다면 코어의 버그인 것 같습니다. 서드파티 자료에서 회원정보를 변경한 후에는 저렇게 캐시를 비워주는 것이 정상이거든요. 캐시를 비워주지 않으면 변경한 것이 효과가 없어요.

     

    예전 글에 제작자분이 캐시 관련하여 의견을 달아주신 것을 보았습니다만, 회원 모듈의 캐시 로직이 워낙 복잡하기 때문에 예상치 못한 버그가 숨어 있을 수도 있습니다. XE의 회원정보는 최소 3단계로 캐시됩니다. 오브젝트 캐시와 전역변수 캐시가 따로 있고, 프로필이미지와 서명 등은 별도의 전역변수를 사용하여 또 캐시됩니다;; 따라서 어느 한쪽의 캐시를 비우자마자 다른 부분의 캐시를 참조하려고 하면 불완전한 데이터가 돌아올 가능성이 충분히 있습니다. (현재 로그인되어 있는 회원 본인의 프로필이미지와 서명이 안 나오는 거죠? 다른 회원의 프로필이미지와 서명은 괜찮고요?)

    modules/member/member.controller.php 맨 아랫부분에 _clearMemberCache 함수가 있는데요... 이 함수 맨 아래에 아래와 같이 한 줄을 추가해 보시기 바랍니다. (중괄호가 여러 겹으로 되어 있으니 어디가 함수 맨 아래인지 정확하게 확인해 주세요 ㅎㅎ)

    unset($GLOBALS['__member_info__'][$member_srl]);

    만약 이것으로 증상이 해결되거나 뭔가 차이가 발생한다면 코어 버그가 맞으니 깃허브에 PR을 하나 넣어야겠습니다.

  • profile profile
    답변 감사합니다. 말씀하신대로 테스트 후 결과를 알려드리겠습니다. 서비스중인 사이트라 갱신 주기는 1시간으로 해야 하니 결과는 조금 시간이 걸릴 수 있습니다. 이전과 같은 결과가 나온다면 너무 잦은 갱신은 불편을 줄 수 있어서요...
  • profile profile
    function _clearMemberCache($member_srl, $site_srl = 0)
    {
    $oCacheHandler = CacheHandler::getInstance('object', NULL, TRUE);
    if($oCacheHandler->isSupport())
    {
    $object_key = 'member_groups:' . getNumberingPath($member_srl) . $member_srl . '_' . $site_srl;
    $cache_key = $oCacheHandler->getGroupKey('member', $object_key);
    $oCacheHandler->delete($cache_key);
    
    if($site_srl !== 0)
    {
    $object_key = 'member_groups:' . getNumberingPath($member_srl) . $member_srl . '_0';
    $cache_key = $oCacheHandler->getGroupKey('member', $object_key);
    $oCacheHandler->delete($cache_key);
    }
    }
    
    $oCacheHandler = CacheHandler::getInstance('object');
    if($oCacheHandler->isSupport())
    {
    $object_key = 'member_info:' . getNumberingPath($member_srl) . $member_srl;
    $cache_key = $oCacheHandler->getGroupKey('member', $object_key);
    $oCacheHandler->delete($cache_key);
    }
    unset($GLOBALS['__member_info__'][$member_srl]);
    }

     

     

    이렇게 추가했습니다.

  • profile profile

    방금 코드 바꿔서 업로드 한 후 (멤머모듈을 먼저 수정하고 애드온을 적용했습니다.)

    제 계정의 프로필이미지와 서명이 회원정보에서 보이지 않네요.

     - 다른 회원이 저의 회원정보를 볼때도 안보입니다.

     

    재미난건    

     

    $oMemberModel = getModel('member');
    $profile_image = $oMemberModel->getProfileImage($logged_info->member_srl);

    {$profile_image->src}

    레이아웃에 요렇게 불러온 경우는 프로필이미지가 보입니다.

  • profile profile
    처음 제안하셨던 것처럼 애드온에서 캐시 갱신 소스를 삭제한 경우에는 괜찮나요?
  • profile profile

    그것 테스트를 해보려 했는데 지금 답변을 주셔서 애드온 그대로 테스트 했습니다.

    추가 테스트 방법을 제안해 주시면 그것을 먼저 해보겠습니다.

  • profile profile

    member.model.php 중간쯤 있는 arrangeMㄷemberInfo 함수 맨 윗부분에 있는

    if(!$GLOBALS['__member_info__'][$info->member_srl])

    조건을 항상 참이 되도록 바꿔보세요. 예를 들면...

    if(TRUE || !$GLOBALS['__member_info__'][$info->member_srl])

    단, 이 상태로 오래 놔두면 서버 부하가 꽤 높아질 수 있기 때문에 테스트만 하시고요,
    이것도 안 된다면 애드온에서 캐시 갱신 소스를 지워보세요.

  • profile profile

    일단 애드온의 캐시 캐싱 소스를 지우는 것을 먼저 해보겠습니다. 현재 그렇게 고쳐 놓은 상태라서요.

  • profile profile
    애드온 맨 윗부분에서 "로그인 상태가 아니면 리턴시키는 코드"를 "관리자가 아니면 리턴시키는 코드"로 바꾸면 갱신 주기를 확 줄여놓고 테스트하시기 더 편리할 것 같네요. ㅎㅎ
  • profile profile
    아.. 그렇게 해보겠습니다. 머리가 잘 돌아가지 않으니 멍청한 테스트를 하네요 ㅋㅌ
  • profile profile

    *60 을 빼면 주기가 어떻게 되는거죠???

    일단 *60 을 빼고 

     

    db에서 마지막로그인 시간을 확인해 보니 시간이 바뀌어 있는 것 보니 적용이 되었습니다.

    캐시 삭제 없이 이 것이 제가 필요한 곳에서 갱신되는지는 회원을 모니터링 해봐야 하니 회원 전체에게 적용해 보겠습니다.

     

    아.. 제가 확인 가능하겠요. 잠시 마지막로그인 출력을 시분초 까지 바꾸면 되겠네요.

     

    ---->>> 이미 로그인 위젯에서 시분초로 출력하고 있는 것이 있었군요. 역시 db에 업데이트 된 것이 캐시 갱신의 도움 없이는 안되네요..  

  • profile profile

    두번째 제안을 주신 테스트시
    멤버모듈 파일 2개를 모두 수정해야 하나요??

    member.model.php 파일만 수정하면 되는 건가요?

     

    우선 member.model.php 만 수정하고 테스트 했습니다. 프로필이미지,서명 문제없이 last_login 값 변경된거 반영됩니다.

     

    부하가 많이 간다고 하시니 원복하겠습니다.

     

    * 어 그런데 원복을 했는데 정상적으로 마지막 로그인 시간과 프로필이미지,서명 모두 제대로 보입니다.

  • profile profile
    이문제는 코어 버그가 아닌 것으로 확인이 될 것 같습니다.

    제가 테스트 과정에서 마지막에 last_login 값 갱신 여부를 바로 확인하기 위해 위젯에 들어가있는 마지막 로그인 출력되는 부분을 확인했습니다.

    이부분 출력이 howlogin.addon.php 애드온에서 사용되는 변수를 이용해 출력했던 것인데요.

    이부분을 애드온이 아닌 코어에서 사용하는 함수로 변경했었습니다.
    이 시점에서 정상화가 된 것 같습니다.

    처음에 개발자분께서 다른 자료의 영향일 것이라는 것이 맞는 듯 합니다. 제가 좀더 정확하게 살펴봣어야 하는데 이 자료는 생각도 못했네요.

    이 자료에서 last_login 관련 부분을 많이 건드리고 있습니다.

    이 자료가 현재 공개되고 있는 애드온이 아니라 코드를 공개하기는 어렵지만 현상이 정상화되는 시점과 비교해 보니 이 자료에서 사용하는 함수를 템플릿에 출력하면 문제가 생기는 것 같습니다.
  • profile profile
    음... 지금 상태가 어떻게 되어 있나요?

    맨 처음 제안드린 것처럼 member.controller.php만 수정하는 것이 가장 깔끔한 방법이고, 이것만으로 해결된다면 가장 좋겠습니다. 그 다음에 제안드린 것처럼 member.model.php를 수정하는 방법은 동일한 효과를 좀더 과격하게 적용하는 거라서요.
  • profile profile
    last_login 시간이 문제가 아니라 프로필이미지와 서명이 문제잖아요. last_login 시간은 DB상에 업데이트만 제대로 되면 캐시 때문에 다르게 표시되더라도 큰 상관은 없습니다.
  • profile profile
    위에 댓글에 달아드렷듯이 다른 애드온의 영향인 것 같습니다. 해당 애드온도 얼마만에 로그인했는지 확인해서 메시지창을 띄워주는 애드온인데 해당 애드온은 자동로그인 대응하기 위해 코드가 들어가 있고 합니다.
    그런데 여기서 쓰는 마지막로그인 변수를 레이아웃에서도 제가 사용해서 출력하도록 하고 있었는데요.(자동로그인에 대응을 하는 것이라..) 이 것을 제거하니 정상화 되는 것 같습니다.

    코어 버그가 아닌 것 같습니다.
  • profile profile
    네. 그런데 이상하게 그 애드온이 영향을 줘서 최근 로그인 갱신 애드온이 갱신할때 프로필 이미지와 서명이 사라지는 현상이 발생합니다.
  • profile profile
    //이전 로그인 값 활용을 위한 처리...
    if($called_position == 'after_module_proc' && $addon_info->login_session != 'N'){

    if($_SESSION['last_logged']){
    Context::set('last_logged',$_SESSION['last_logged']);
    }
    //자동로그인의 경우 현재 로그인 정보를 출력
    else{
    $logged_info = Context::get('logged_info');
    Context::set('last_logged',$logged_info->last_login);
    }
    }


    이런 부분도 있구요...
  • profile profile
    if($called_position == 'before_display_content' && Context::get('act') != 'procMemberLogin'){

    if(!$_SESSION['login_text']) return;

    $last_login = $_SESSION['login_text'];

    $howlogin_script="
    <script type=\"text/javascript\">//<![CDATA[
    var lastlogin = '$last_login';
    alert(lastlogin);
    //]]>
    </script>
    ";

    //타임설정 체크
    $timing = $addon_info->login_alert_timing;

    $timing_alert = 'Y';

    if($timing && $timing != 'all'){
    require_once('./addons/howlogin/func/howlogin.func.php');
    $howlogin = new howlogin;
    $timing_alert = $howlogin->getTime($_SESSION['last_logged'], $timing);
    }

    if($addon_info->login_alert != 'N' && $timing_alert == 'Y'){
    Context::addHtmlHeader($howlogin_script);
    }

    unset($_SESSION['login_text']);
    }





    이런 부분도 있습니다.
  • profile profile

    제가 임의로 레이아웃에 {$last_logged} 로 마지막 로그인 시간을 출력하고 있었습니다. 자동로그인에도 갱신된 시간이 확보가 되어서요...

    오늘 테스트 과정에서 이것을 레이아웃에서 제거하니 정상이 된 것 입니다.

  • profile profile
    또 한기지 특이사항으로 참고할만한 내용이
    https://xe1.xpressengine.com/index.php?mid=download&package_id=22753636

    저희는 위 모듈을 사용중입니다.

    FAQ
    Q : 이 모듈을 설치하면 XE의 자동로그인은 어떻게 되나요?
    A : XE내장된 기능은 무시되고 본 모듈이 전부 처리합니다.(기술적으로 xeak 쿠키를 무조건 제거하고, xe에 내장된 자동로그인 테이블을 이용하지 않도록 처리합니다.)

    이런내용이 있는데요.

    자동로그인모듈 + 얼마만이니 애드온 + 레이아웃에 얼마만이니에서 만들어진 변수 레이아웃에서 사용 + 최근 로그인갱신 애드온

    이런 조합 이어서 이 어디선가 영향을 준 것 일 수 도 있을 것 같습니다.
  • profile profile
    네... 변수가 무척 많네요 ㅎㅎ
  • profile profile
    처음부터 원인을 제대로 파악하지 못한 제 잘못이 크긴 한데요. 어찌 되었던 이 의문점 내지는 숙제는 1년짜리 고민거리였네요. 해결이되어서 자동로그인 하는 분들(저희는 앱 사용시 자동로그인)의 마지막 로그인 데이터가 실제가 가깝게 보정될 수 있어 좋네요.
  • profile profile
    오늘 또 한번 이런 현상이 발생했네요. 매번 높은 빈도로 발생했던 것은 얼마만이니? 애드온이 원인이어서 해당 애드온을 사용중지 하고 거의 발생하지 않고 있었는데 오늘 우연히 썸씽모듈에서 프로필영역을 보다가 동일한 현상이 재발한 것을 확인했습니다.

    일단 제가 발견하기 이전 시점 1시간 사이에 제가 어떤 페이지를 열었을때 자동로그인갱신애드온의 캐시시업데이트 쿼리가 동작하고 또 다른 자료에서 영향을 준것이 반영되어 두가지 정보가 표시되지 않는 상태가 되었습니다.

    혹시 지난번에 그래도 pr을 넣는게 좋겠다고 하신 것 해주시면 좋을 것 같습니다.
  • profile profile
    음.. 완전히 해결된 것이 아니었군요.
  • profile profile
    네. 이미 지나간 시간에 발생한 거라 어떤 시점에 그랬는지 확인이 어렵네요. 애그온에서 마지막로그인 갱신 하는 동작할때 이미 다른자료에서 뭔가 영향을 준 상태라는 것만 추측이 가능할 뿐이네요....
  • profile profile
    정확히 이게 원인인지는 모르겠지만, 일단 pr을 제출해 보았습니다.
    https://github.com/xpressengine/xe-core/pull/2372
  • profile profile
    감사합니다. 일단 저번에 문제를 일으키는 애드온은 100% 계속 업데이트때마다 문제를 일으키고 있었고 지금은 굉장히 찾기 어려운 어떠한 특수한 상황에서 발생한 것 같긴한데 찾기는 어려울 것 같습니다.
    해당 pr이 이러한 문제 발생 방지에 도움이 되었으면 합니다.
  • ?
    @웹지기 님 안녕하세요!
    howlogin 애드온 저도 사용중인데!

    혹시 웹지기님 사이트 php7.0 버전 아니신가요!?
    php7 에서 해당 애드온 오류가 나진 않으신지?
  • ? profile
    7.2 입니다. 7.0 때는 썼는데 지금은 안씁니다.

    7.0과 7.1에서 다른 상황일 수 있습니다. 오류가 있어도 7.0에서는 문제가 안나타날 수 있습니다.