CMS/프레임워크 | XE 1.x |
---|---|
개발 언어 | PHP 7.0 |
문제 페이지 주소 | 비공개 (작성 후 5일 경과) |
제작자분께서는 그럴리가 없다고 하셨지만 저희 사이트 환경에서는 오류가 발생합니다.
1시간 단위로 갱신하게 해 놓았을때 로그인한 회원이 활동중에 해당 애드온에 의해 갱신이 될 때
프로필이미지와 서명을 가져오지 못하는 상황이 됩니다.
이때 로그아웃 후 다시 로그인을 하면 다시 제대로된 정보를 가져올 수 있게 됩니다.
각종 스킨등에서 프로필이미지와 서명을 가져오는 것은 모두 비슷한 방식을 사용할 것 입니다.
로그인이 아니면 리턴시키는 코드
로그인변수 담기
갱신시간이 안되었으면 리턴시키는 코드
$args = new stdClass;
$args->member_srl = $logged_info->member_srl;
executeQuery('member.updateLastLogin', $args);
$oMemberController = getController('member');
$oMemberController->_clearMemberCache($logged_info->member_srl);
로그인변수 담기
갱신시간이 안되었으면 리턴시키는 코드
$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);
부분을 제거해도 로그인시간 갱신에 문제가 없을지도 궁금합니다.
*라이센스와 별개로 포인트가 무료가 아닌 자료라 코드의 일부만 게시하고 일부는 설명으로 대체했습니다.
댓글 30
딱 저렇게 캐시를 비우는 코드뿐인데도 프로필이미지, 서명 등 일부 회원정보가 증발한다면 코어의 버그인 것 같습니다. 서드파티 자료에서 회원정보를 변경한 후에는 저렇게 캐시를 비워주는 것이 정상이거든요. 캐시를 비워주지 않으면 변경한 것이 효과가 없어요.
예전 글에 제작자분이 캐시 관련하여 의견을 달아주신 것을 보았습니다만, 회원 모듈의 캐시 로직이 워낙 복잡하기 때문에 예상치 못한 버그가 숨어 있을 수도 있습니다. XE의 회원정보는 최소 3단계로 캐시됩니다. 오브젝트 캐시와 전역변수 캐시가 따로 있고, 프로필이미지와 서명 등은 별도의 전역변수를 사용하여 또 캐시됩니다;; 따라서 어느 한쪽의 캐시를 비우자마자 다른 부분의 캐시를 참조하려고 하면 불완전한 데이터가 돌아올 가능성이 충분히 있습니다. (현재 로그인되어 있는 회원 본인의 프로필이미지와 서명이 안 나오는 거죠? 다른 회원의 프로필이미지와 서명은 괜찮고요?)
modules/member/member.controller.php 맨 아랫부분에 _clearMemberCache 함수가 있는데요... 이 함수 맨 아래에 아래와 같이 한 줄을 추가해 보시기 바랍니다. (중괄호가 여러 겹으로 되어 있으니 어디가 함수 맨 아래인지 정확하게 확인해 주세요 ㅎㅎ)
unset($GLOBALS['__member_info__'][$member_srl]);
만약 이것으로 증상이 해결되거나 뭔가 차이가 발생한다면 코어 버그가 맞으니 깃허브에 PR을 하나 넣어야겠습니다.
{
$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]);
}
이렇게 추가했습니다.
방금 코드 바꿔서 업로드 한 후 (멤머모듈을 먼저 수정하고 애드온을 적용했습니다.)
제 계정의 프로필이미지와 서명이 회원정보에서 보이지 않네요.
- 다른 회원이 저의 회원정보를 볼때도 안보입니다.
재미난건
$oMemberModel = getModel('member');
$profile_image = $oMemberModel->getProfileImage($logged_info->member_srl);
{$profile_image->src}
레이아웃에 요렇게 불러온 경우는 프로필이미지가 보입니다.
그것 테스트를 해보려 했는데 지금 답변을 주셔서 애드온 그대로 테스트 했습니다.
추가 테스트 방법을 제안해 주시면 그것을 먼저 해보겠습니다.
member.model.php 중간쯤 있는 arrangeMㄷemberInfo 함수 맨 윗부분에 있는
if(!$GLOBALS['__member_info__'][$info->member_srl])
조건을 항상 참이 되도록 바꿔보세요. 예를 들면...
if(TRUE || !$GLOBALS['__member_info__'][$info->member_srl])
단, 이 상태로 오래 놔두면 서버 부하가 꽤 높아질 수 있기 때문에 테스트만 하시고요,
이것도 안 된다면 애드온에서 캐시 갱신 소스를 지워보세요.
일단 애드온의 캐시 캐싱 소스를 지우는 것을 먼저 해보겠습니다. 현재 그렇게 고쳐 놓은 상태라서요.
*60 을 빼면 주기가 어떻게 되는거죠???
일단 *60 을 빼고
db에서 마지막로그인 시간을 확인해 보니 시간이 바뀌어 있는 것 보니 적용이 되었습니다.
캐시 삭제 없이 이 것이 제가 필요한 곳에서 갱신되는지는 회원을 모니터링 해봐야 하니 회원 전체에게 적용해 보겠습니다.
아.. 제가 확인 가능하겠요. 잠시 마지막로그인 출력을 시분초 까지 바꾸면 되겠네요.
---->>> 이미 로그인 위젯에서 시분초로 출력하고 있는 것이 있었군요. 역시 db에 업데이트 된 것이 캐시 갱신의 도움 없이는 안되네요..
두번째 제안을 주신 테스트시
멤버모듈 파일 2개를 모두 수정해야 하나요??
member.model.php 파일만 수정하면 되는 건가요?
우선 member.model.php 만 수정하고 테스트 했습니다. 프로필이미지,서명 문제없이 last_login 값 변경된거 반영됩니다.
부하가 많이 간다고 하시니 원복하겠습니다.
* 어 그런데 원복을 했는데 정상적으로 마지막 로그인 시간과 프로필이미지,서명 모두 제대로 보입니다.
맨 처음 제안드린 것처럼 member.controller.php만 수정하는 것이 가장 깔끔한 방법이고, 이것만으로 해결된다면 가장 좋겠습니다. 그 다음에 제안드린 것처럼 member.model.php를 수정하는 방법은 동일한 효과를 좀더 과격하게 적용하는 거라서요.
그런데 여기서 쓰는 마지막로그인 변수를 레이아웃에서도 제가 사용해서 출력하도록 하고 있었는데요.(자동로그인에 대응을 하는 것이라..) 이 것을 제거하니 정상화 되는 것 같습니다.
코어 버그가 아닌 것 같습니다.
제가 테스트 과정에서 마지막에 last_login 값 갱신 여부를 바로 확인하기 위해 위젯에 들어가있는 마지막 로그인 출력되는 부분을 확인했습니다.
이부분 출력이 howlogin.addon.php 애드온에서 사용되는 변수를 이용해 출력했던 것인데요.
이부분을 애드온이 아닌 코어에서 사용하는 함수로 변경했었습니다.
이 시점에서 정상화가 된 것 같습니다.
처음에 개발자분께서 다른 자료의 영향일 것이라는 것이 맞는 듯 합니다. 제가 좀더 정확하게 살펴봣어야 하는데 이 자료는 생각도 못했네요.
이 자료에서 last_login 관련 부분을 많이 건드리고 있습니다.
이 자료가 현재 공개되고 있는 애드온이 아니라 코드를 공개하기는 어렵지만 현상이 정상화되는 시점과 비교해 보니 이 자료에서 사용하는 함수를 템플릿에 출력하면 문제가 생기는 것 같습니다.
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);
}
}
이런 부분도 있구요...
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']);
}
이런 부분도 있습니다.
제가 임의로 레이아웃에 {$last_logged} 로 마지막 로그인 시간을 출력하고 있었습니다. 자동로그인에도 갱신된 시간이 확보가 되어서요...
오늘 테스트 과정에서 이것을 레이아웃에서 제거하니 정상이 된 것 입니다.
https://xe1.xpressengine.com/index.php?mid=download&package_id=22753636
저희는 위 모듈을 사용중입니다.
FAQ
Q : 이 모듈을 설치하면 XE의 자동로그인은 어떻게 되나요?
A : XE내장된 기능은 무시되고 본 모듈이 전부 처리합니다.(기술적으로 xeak 쿠키를 무조건 제거하고, xe에 내장된 자동로그인 테이블을 이용하지 않도록 처리합니다.)
이런내용이 있는데요.
자동로그인모듈 + 얼마만이니 애드온 + 레이아웃에 얼마만이니에서 만들어진 변수 레이아웃에서 사용 + 최근 로그인갱신 애드온
이런 조합 이어서 이 어디선가 영향을 준 것 일 수 도 있을 것 같습니다.
일단 제가 발견하기 이전 시점 1시간 사이에 제가 어떤 페이지를 열었을때 자동로그인갱신애드온의 캐시시업데이트 쿼리가 동작하고 또 다른 자료에서 영향을 준것이 반영되어 두가지 정보가 표시되지 않는 상태가 되었습니다.
혹시 지난번에 그래도 pr을 넣는게 좋겠다고 하신 것 해주시면 좋을 것 같습니다.
https://github.com/xpressengine/xe-core/pull/2372
해당 pr이 이러한 문제 발생 방지에 도움이 되었으면 합니다.
howlogin 애드온 저도 사용중인데!
혹시 웹지기님 사이트 php7.0 버전 아니신가요!?
php7 에서 해당 애드온 오류가 나진 않으신지?
7.0과 7.1에서 다른 상황일 수 있습니다. 오류가 있어도 7.0에서는 문제가 안나타날 수 있습니다.