Tomcat6(7버전도 동일, 이하 Tomcat)에서는 쿠키에 특수문자인 = (이하 equals)가 포함되어 있어면, 쿠키를 꺼낼때 equals 문자 뒤로는 문자열을 출력하지 못한다. 이유는, Tomcat의 기본 설정이Cookie Version 0 을 따르도록 되어 있기때문이다. 특수 문자는 Cookie Version 1 부터 사용 가능하다.
With Version 0 cookies, values should not contain white space, brackets, parentheses, equals signs, commas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.
Tomcat은 기본적으로 Cookie Version 0을 따르지만, 특수 문자가 포함된 쿠키를 굽거나 꺼낼 수 있다. 하지만 이는 " 로 묶어서 Cookie 를 발급하는 방법으로 쿠키 value 값 자체에 " 가 포함되어 발급되기 때문에 이 를 읽는 다른 서버 혹은 javascript에서는 " 를 제거 하고 읽어야 하는 문제가 발생 한다. 즉, 기본적으로 제공하는 " 를 붙여서 사용하는 방식은 다른 플랫폼에서 " 를 제거하고 읽어야 하는 번거러움이 발생한다.
근본적으로 Cookie Version 0을 지원하도록 하는 방법은 아래와 같이 catalina.properties 를 설정하는 방법이 있다.
org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE=true # 쿠키에 = 문자열을 포함을 허용 설정 org.apache.catalina.STRICT_SERVLET_COMPLIANCE= true # 쿠키에 = 문자열을 포함하여 쿠키를 구워도 "표가 붙지 않도록 설정
하지만, 소규모가 아니라면 같은 도메인으로 묶인 모든 서버의 설정을 바꾸기란 쉬운일이 아니다. 그래서 방법이 있어도 좋은 해결책은 될 수 없다. 자 그렇다면 이제 Cookie 를 version 0 스펙에 맞추는 방법밖에 없다. 그런 방법은 아래처럼 url 인코딩을 통하여 특수 문자를 encode를 하여 사용한다. 물론, 읽을 때도 원본 값을 얻기 위해서는 decode를 해줘야 한다.
Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8")); // set String value = URLDecoder.decode(cookie.getValue(), "UTF-8")); // get
하지만, 만약에 Tomcat이 기본적으로 Cookie Version 0을 지원한다는 사실을 모르고 다른서버에서 encode하지 않고 미리 발급을 한 Cookie 가 있다면 어떻게 해야 하는가?
이 경우는 아래처럼 Cookie를 읽는 메서드를 따로 구현하여 특수 문자가 포함된 Cookie를 읽을 수 있다.. 조금만 코드를 읽어보면 Cookie 전체를 인자로 넘기고 key : value 로 파싱하여 넘겨준다.
public static Map<String, Cookie> parseCookies(String cookieHeader)
{
Map<String, Cookie> result = new LinkedHashMap<String, Cookie>();
if (cookieHeader != null)
{
String[] cookiesRaw = cookieHeader.split("; ");
for (int i = 0; i < cookiesRaw.length; i++)
{
String[] parts = cookiesRaw[i].split("=", 2);
String value = parts.length > 1 ? parts[1] : "";
if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\""))
{
value = value.substring(1, value.length() - 1);
}
result.put(parts[0], new Cookie(parts[0], value));
}
}
return result;
}
Tomcat 6에서 테스트 했으며, 다른 서버는 어떤 Cookie Version을 따르는지 조사하지 않았다. 하지만, 흔히 사용되는 Tomcat이 기본적으로 Cookie Version 0을 따른다고 하면, Cookie 를 발급할때 Version 0 스펙을 따르는 것이 안전 하다.
즉, 발급 되는 모든 쿠키는 위에 언급된 특수문자를 포함 하지 않거나, 혹은 굳이 포함이 되어야 한다면 URL인코딩을 통하여 쿠키를 발급하여 사용 하도록 해야 한다.
posted by 파란 별
Recent Comment