[PHP/CI] 코드이그나이터(Codeigniter)에서 한글 URI가 막힐 때

2015-12-26 12:17:00에 작성됨 | PHP, MySQL, 프로그래밍

http://website.com/posts/search/검색어

코드이그나이터에서 개발을 하다 보면 위와 같이 한글로 된 URI를 패스해야 할 때가 있는데
기본적으로 코드이그나이터에서는 보안상의 이유로 몇몇 허용된 글자 이외의 글자는 모두 URI로 넘기는 것이 막혀 있다. 그래서 기본적으로 저렇게 넘기면 오류 페이지가 뜨게 된다.

일단 처음 시도하면 간단하게 할 수 있는 것은 config.php 에 permitted 에 가-힣을 추가가하는 것이다.

/application/config/config.php 에 permitted_uri_chars 항목을 찾아서 추가한다.

$config[‘permitted_uri_chars’] = “가-힣a-z 0-9~%.:_-“;

근데 이렇게 했는데도 여전히 보안상의 이유로 오류 나는 경우가 있는데, 이는 브라우저가 URI을 전송할 때
EUC-KR로 전송하는 경우 그렇게 된다. 만약 CI를 EUC-KR로 작성하고 있다면 별 문제 없지만
UTF-8로 작성하는 경우 또 골치아프게 된다(본래라면 이렇게 짜는게 맞다.) 그렇다고 고객한테 브라우저 설정바꾸라고 할 수도 없고…

프로젝트 전체를 UTF-8을 EUC-KR로 바꾸는 것보단 다음과 같이 필요한 부분만 변환시켜주면 된다.

/system/core/URI.php 를 열어서 function _filter_url을 찾아 다음 글씨 굵은 부분을 추가한다. (CI 3이상 버전은 filter_url 이다)

function _filter_uri($str)
{
    $uri_encode = mb_detect_encoding($str, 'UTF-8, EUC-KR, ISO-8859-1');
    if($uri_encode != 'UTF-8' && $uri_encode !== false)  {
        $str = mb_convert_encoding($str,"utf-8",$uri_encode);
    }

    if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
    {
        // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
        // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
        if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
        {
            show_error('The URI you submitted has disallowed characters.', 400);
        }
    }

    // Convert programatic characters to entities
    $bad    = array('$',        '(',        ')',        '%28',        '%29');
    $good    = array('$',    '(',    ')',    '(',    ')');

    return str_replace($bad, $good, $str);
}

위 소스는 당연히 UTF-8 이외의 인코딩 글자가 들어오면 UTF-8로 변환후 사용하겠다는 것이다. 이렇게하면 CI에서 가-힣을 정확하게 판별하여 한글도 무해한 문자로 인식하고 통과시켜 준다.

PS 거의 반년 만에 포스팅이라니…

Leave a Reply

Your email address will not be published. Required fields are marked *