CI 묻고 답하기

제목 URL을 seqment로 전달하는 방법
글쓴이 초원을달리는유부남 작성시각 2009/12/28 15:58:13
댓글 : 4 추천 : 0 스크랩 : 0 조회수 : 37166   RSS
안녕하세요~
로그인 인증 페이지에서 로그인이 안되어 있으면, 로그인 후 현재의 페이지로 돌아오는 부분에서 문제가
발생하였습니다.

URL에 urlencode 값을 sequment로 넣었더니, 페이지가 열리지 않습니다.
어떻게들 해결하시는지요?


http://www.example.com/members/login_form/rtn_url/%2Fmembers%2Flogin_area%2F

호출하면 아래처럼 에러가 납니다.

객체 없음!

요청한 URL을 이 서버에서 찾을 수 없습니다. 이전 페이지에 있는 링크가 잘못되었거나 오래되어 없어진 것 같습니다. 그 페이지를 만든이에게 이 사실을 알려주시기 바랍니다.

만약 이것이 서버 오류라고 생각되면, 웹 관리자에게 연락하시기 바랍니다.

Error 404

www.example.com
2009-12-28 ¿ÀÈÄ 3:57:23
Apache/2.2.12 (Win32) DAV/2 mod_ssl/2.2.12 OpenSSL/0.9.8k mod_autoindex_color PHP/5.3.0 mod_perl/2.0.4 Perl/v5.10.0
 다음글 결국 CI session library는 (9)
 이전글 라이브러리에서 session 불러오는법? (12)

댓글

헛발이 / 2009/12/28 16:11:30 / 추천 0

혹시 이 문제 아닌가요? 저도 전에 웅파님께 들은 이이기 인데요...
config에서
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';   //이부분을
$config['permitted_uri_chars'] = ''; 이렇게 해서 해결된적이 있었는데..
이 문제는 아닌가요?

http://codeigniter-kr.org/qna/view/1645/page/2/


아니면 웹관리자에게 물어 보셔야 할듯 싶은데요... ^^;

변종원(웅파) / 2009/12/28 16:14:12 / 추천 0
%2F 이게 "/"죠.... 결국..
/rtn_url//members/login_area/ 이렇게 되서 에러가 생길 수 있습니다.
전 base64_encode()로 처리하고 있습니다.
포럼 로그인 부분 소스 보시면 될겁니다.
http://codeigniter-kr.org/auth/login/L2luZGV4LnBocA==

아. 맞다. 헛발이님 말씀도 맞습니다. ^^

추가. rawurlencode()을 이용하셔도 됩니다.

초원을달리는유부남 / 2009/12/29 10:15:36 / 추천 0

[설정]
$config['permitted_uri_chars'] = '';

[슬래시 사이의 값의 구분값]
base64_encode() 함수로 감싼다.

해결되었습니다. 감사합니다.

tuyitu719 / 2026/03/14 10:50:29 / 추천 0

 

문제는 CodeIgniter가 아니라 Apache가 먼저 막는 것입니다. URL 세그먼트에 %2F 같은 인코딩된 슬래시가 들어가면, Apache는 기본값에서 이를 허용하지 않고 404 Not Found를 반환합니다. Apache의 AllowEncodedSlashes 기본값은 Off이고, 이 경우 %2F가 포함된 요청은 404로 거절됩니다.

즉,
/members/login_form/rtn_url/%2Fmembers%2Flogin_area%2F
이 주소는 CI까지 도달하기 전에 웹서버에서 끊기는 것입니다. 그래서 애플리케이션 코드에서 urldecode()를 하기도 전에 이미 404가 나는 것입니다.

보통 해결 방법은 3가지입니다.

1. 가장 안전한 방법: 세그먼트 대신 GET 파라미터로 넘기기
예를 들어
/members/login_form?rtn_url=%2Fmembers%2Flogin_area%2F
처럼 처리하면, 경로(path) 안에 %2F를 넣지 않으므로 Apache 404를 피할 수 있습니다. 로그인 후에는 $_GET['rtn_url'] 또는 CI 입력 클래스로 받아서 리다이렉트하면 됩니다. 이 방법이 가장 흔하고 안전합니다.

2. URL-safe 인코딩을 따로 사용하기
반드시 세그먼트로 넘겨야 한다면 /가 들어가지 않도록 base64 후 URL-safe 치환을 해서 넘기는 방법을 씁니다. 예를 들면 +, /, = 문자를 다른 문자로 바꿔 세그먼트에 넣고, 받은 뒤 다시 복원하는 방식입니다. 이렇게 하면 Apache가 %2F를 슬래시로 해석할 일이 없습니다.

3. Apache 설정 변경
서버 설정을 바꿀 수 있다면 AllowEncodedSlashes On으로 허용할 수 있습니다. Apache 문서에도 %2F 같은 encoded slash는 기본적으로 404가 나며, AllowEncodedSlashes로 제어한다고 나와 있습니다. 다만 이건 서버 전체 정책과 보안 측면을 같이 봐야 해서, 실무에서는 보통 1번이나 2번을 더 많이 권장합니다.

답변 예시는 이렇게 쓰면 자연스럽습니다:


 
 
원인은 CodeIgniter가 아니라 Apache입니다.

URI segment 안에 urlencode() 된 값(%2F 등)을 넣으면,
Apache가 encoded slash를 기본적으로 허용하지 않아서
CI로 요청이 들어오기 전에 404를 반환합니다.

즉,
/members/login_form/rtn_url/%2Fmembers%2Flogin_area%2F
같은 형태는 피하셔야 합니다.

해결 방법은 보통 두 가지입니다.

1) return URL은 segment가 아니라 GET 파라미터로 넘긴다.
예)
/members/login_form?rtn_url=%2Fmembers%2Flogin_area%2F

2) 꼭 segment를 써야 하면 base64 같은 방식으로
URL-safe 하게 변환해서 넘긴 뒤, 컨트롤러에서 복원한다.

서버 설정을 건드릴 수 있다면 Apache의
AllowEncodedSlashes On
설정으로 처리할 수도 있지만,
보통은 GET 방식이 가장 단순하고 안전합니다.