세션 유지 시간을 늘려 달라는 요청을 받고 설정 파일에서 값을 바꿨는데 그대로였다.
Table of contents
Open Table of contents
같은 값이 두 곳에 있었다
기본 설정 파일에서 2시간으로 고쳤는데 config->item 으로 찍어 보니 1800 이 나왔다. 어디서 오는지 찾았다.
$ grep -rn "sess_expiration" application/
application/config/config.php:283:$config['sess_expiration'] = 7200;
application/config/production/config.php:41:$config['sess_expiration'] = 1800;
환경별 설정 디렉터리가 따로 있었다. 처음에는 그 안의 파일이 기본 파일 위에 덮이는 것으로 알았는데 소스를 보니 아니었다.
get_config() 는 ENVIRONMENT 가 정의돼 있고 그 이름의 디렉터리에 config.php 가 있으면 그것을 읽고 끝낸다. 없을 때만 기본 파일로 내려간다. 둘을 합치는 코드가 없다.
그러니 덮는 것이 아니라 대체하는 것이다. 내가 고친 기본 파일은 운영에서 아예 안 읽힌다. 더 걸리는 것은 기본 파일에만 있고 환경별 파일에 없는 키다. 그런 키는 값이 작아지는 것이 아니라 FALSE 가 된다.
층이 셋이었다
층은 하나 더 있었다. 서버의 PHP 설정이다.
session.gc_maxlifetime = 1440
여기서 갈리는 것이 있었다. sess_expiration 은 프레임워크가 자기 쿠키에 넣는 만료 시각이고 session.gc_maxlifetime 은 PHP 가 자기 세션 파일을 치우는 기준이다. 서로 다른 것을 가리킨다.
어느 쪽 세션을 쓰느냐에 따라 걸리는 층이 다르다. 프레임워크 세션만 쓰면 PHP 쪽 값은 상관이 없고 session_start 를 쓰는 자리가 섞여 있으면 그쪽이 걸린다. 우리는 섞여 있었다. 서버 설정을 고칠 권한이 없어서 코드에서 함께 지정했다.
ini_set('session.gc_maxlifetime', 7200);
어느 층에서 정할지 정했다
값마다 어느 층에서 정할지 규칙을 세웠다. 다만 대체 방식이라 환경별 파일이 있으면 그 파일 하나에 전부 있어야 한다. 기본 파일은 환경별 파일이 없는 환경에서만 쓰인다.
세션 시간은 환경마다 다를 이유가 없어서 양쪽에 같은 값을 두고 왜 그 값인지를 적었다. 한쪽에서 빼면 그 환경에서 값이 사라진다.
// 관리자 작업 시간을 고려해 2시간. 운영·시험 동일.
$config['sess_expiration'] = 7200;
양쪽 키를 array_diff_key 로 맞대 봤다. 기본 파일에만 있는 키가 여럿 나왔고 그것들은 운영에서 전부 FALSE 로 읽히고 있었다. log_threshold 는 운영이 오류만 남기고 시험이 전부 남기니 달라야 맞고 upload_path 와 encryption_key 도 달라야 맞다. 다른 것은 값을 맞춰 넣었다.
최종 값을 보는 화면
설정이 여러 층이면 최종 값을 확인할 방법이 필요하다. 파일을 찾아다니는 대신 읽어 나온 값을 그대로 보여 주는 화면을 만들었다.
public function config_check()
{
if (ENVIRONMENT === 'production') { show_404(); return; }
$keys = ['sess_expiration', 'base_url', 'upload_path', 'log_threshold'];
foreach ($keys as $k) {
echo $k . ' = ' . var_export($this->config->item($k), true) . "\n";
}
echo "\nPHP:\n";
echo 'session.gc_maxlifetime = ' . ini_get('session.gc_maxlifetime') . "\n";
echo 'upload_max_filesize = ' . ini_get('upload_max_filesize') . "\n";
}
config->item 이 돌려주는 값과 ini_get 값을 함께 찍는 것이 요점이었다. 이번 문제가 두 층에 걸쳐 있었기 때문이다. ENVIRONMENT 가 운영이면 show_404 로 막았다. 설정 값이 밖으로 나가면 안 된다.
정리
- 계층이 몇 개인지와 어떻게 합쳐지는지를 소스로 확인한다
get_config()는 환경별config.php가 있으면 기본 파일을 안 읽는다- 덮는 것이 아니라 대체라 기본 파일에만 있는 키는
FALSE가 된다 array_diff_key로 양쪽 키를 맞대 본다sess_expiration과session.gc_maxlifetime은 서로 다른 것을 가리킨다- 어느 쪽 세션을 쓰느냐에 따라 걸리는 층이 다르다
config->item과ini_get을 함께 찍는 확인 화면을 만든다- 그 화면은
ENVIRONMENT가 운영이면show_404로 막는다