[http] 쿠키를 서버 측에서 삭제하는 올바른 방법

인증 프로세스를 위해 사용자가 로그인 할 때 고유 토큰을 생성하고이를 인증에 사용되는 쿠키에 넣습니다.

그래서 나는 서버에서 이와 같은 것을 보낼 것입니다 :

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

어느 브라우저에서나 작동합니다. 그런 다음 쿠키를 삭제하려면 expires1970 년 1 월 1 일에 설정된 필드 와 유사한 쿠키를 보냅니다.

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC;

Firefox에서는 잘 작동하지만 IE 또는 Safari에서는 쿠키를 삭제하지 않습니다.

쿠키를 삭제하는 가장 좋은 방법은 무엇입니까? 과거의 만기 설정 방법은 부피가 커 보입니다. 또한 왜 이것이 FF에서는 작동하지만 IE 또는 Safari에서는 작동하지 않습니까?



답변

와 같은 쿠키 값을 보내기 ; expires추가하면 쿠키를 파괴하지 않습니다.

빈 값을 설정하여 쿠키를 무효화하고 expires필드도 포함하십시오.

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

모든 브라우저가 쿠키를 삭제하도록 강요 할 수는 없습니다. 클라이언트는 쿠키가 만료 된 경우에도 쿠키가 유지되도록 브라우저를 구성 할 수 있습니다. 위에서 설명한대로 값을 설정하면이 문제가 해결됩니다.


답변

이 답변을 작성할 때이 질문에 대한 수락 된 대답 은 브라우저가 Expires값이 과거 인 대체 쿠키를받을 때 쿠키를 삭제할 필요가 없음을 나타 냅니다. 그 주장은 거짓이다. Expires과거로 설정 하는 것은 쿠키를 삭제하는 표준의 사양을 준수하는 방법이며,이를 위해서는 사용자 에이전트가 사양에 필요합니다.

Expires과거에 속성을 사용하여 쿠키를 삭제하는 것은 정확하며 사양에 의해 지시 된 쿠키를 제거하는 방법입니다. RFC 6255 의 예제 섹션은 다음과 같습니다.

마지막으로 쿠키를 제거하기 위해 서버는 과거에 만료 날짜가있는 Set-Cookie 헤더를 반환합니다. Set-Cookie 헤더의 Path 및 Domain 속성이 쿠키를 만들 때 사용 된 값과 일치하는 경우에만 서버가 쿠키를 성공적으로 제거합니다.

사용자 에이전트 요구 사항 섹션 함께 사용자 에이전트가 그 유효 기간이 과거에 같은 이름으로 새 쿠키를받는 경우 쿠키 즉시 영구 삭제해야 효과가 다음과 같은 요구 사항을 포함

  1. [새 쿠키를받을 때] 쿠키 저장소에 새로 만든 쿠키와 이름, 도메인 및 경로가 같은 쿠키가 포함 된 경우 :

    1. 이전 쿠키의 작성 시간과 일치하도록 새로 작성된 쿠키의 작성 시간을 업데이트하십시오.
    2. 쿠키 저장소에서 기존 쿠키를 제거하십시오.
  2. 새로 작성된 쿠키를 쿠키 저장소에 삽입하십시오.

쿠키의 유효 기간이 지난 쿠키는 “만료”됩니다.

쿠키 에이전트에 쿠키가 만료 된 경우 언제든지 사용자 에이전트는 쿠키 쿠키에서 만료 된 쿠키를 모두 제거해야합니다.

위의 11-3, 11-4 및 12 지점은 이름, 도메인 및 경로가 동일한 새 쿠키가 수신 될 때 기존 쿠키를 정리하고 새 쿠키로 교체해야 함을 의미합니다. 마지막으로 만료 된 쿠키에 대한 아래 사항은 해당 쿠키가 완료된 후 쿠키 즉시 제거 해야 함을 나타냅니다 . 이 사양은이 시점에서 브라우저에 흔들리지 않는 공간을 제공합니다. 브라우저가 사용자에게 쿠키 만료를 비활성화하는 옵션을 제공하면 허용되는 답변에서 일부 브라우저가 제안하는 것처럼 사양을 위반하는 것입니다. (이러한 기능은 거의 사용되지 않으며 내가 아는 한 브라우저에 존재하지 않습니다.)

그렇다면이 질문의 OP가 왜이 접근법이 실패 했는가? Internet Explorer의 복사본을 제거하여 동작을 확인하지는 않았지만 OP의 Expires값이 잘못 되었기 때문일 것입니다 . 그들은이 값을 사용했다 :

expires=Thu, Jan 01 1970 00:00:00 UTC;

그러나 이것은 두 가지 방식으로 구문 상 유효하지 않습니다.

사양 의 구문 섹션Expires속성 의 값이

rfc1123 -date, [RFC2616], 섹션 3.3.1에 정의 됨

위의 두 번째 링크를 따라 다음과 같은 형식의 예를 찾을 수 있습니다.

Sun, 06 Nov 1994 08:49:37 GMT

구문 정의가 …

  1. 날짜 는 질문자가 사용하는 월 일 년 형식이 아닌 일 월 연도 형식 으로 작성해야합니다 .

    구체적 rfc1123-date으로 다음과 같이 정의 됩니다.

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    다음과 date1같이 정의 합니다.

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    

  1. UTC시간대로 허용되지 않습니다 .

    스펙에는이 형식으로 허용되는 시간대 오프셋에 대한 다음 명령문이 포함되어 있습니다.

    모든 HTTP 날짜 / 시간 스탬프는 예외없이 그리니치 표준시 (GMT)로 표시되어야합니다.

    우리는이 날짜 형식의 원래 사양으로 깊이 파고 경우 무엇보다, 우리의 초기 사양에 그 발견 https://tools.ietf.org/html/rfc822을구문 섹션 목록 “UT는”( “세계시”를 의미 ) 가능한 값으로 만 수행 되지 목록이 유효하지 않습니다 같은 UTC (협정 세계시). 내가 아는 한,이 날짜 형식에서 “UTC”를 사용하는 것은 결코 유효 하지 않습니다. 형식이 처음 1982 년에 지정하고, HTTP 스펙은 엄격하게 채택 할 때 유효한 값 아니었다 “GMT”를 제외한 모든 “영역”값의 사용을 금지하여 형식의 제한 버전.

여기서 질문자 asker 대신 thisExpires 와 같은 속성을 사용한 경우 :

expires=Thu, 01 Jan 1970 00:00:00 GMT;

아마도 그것은 효과가 있었을 것입니다.


답변

쿠키를 삭제하는 표준 방법은 “만료”를 지난 날짜로 설정하는 것입니다.

날짜 형식이 기존 형식이 아니기 때문에 문제가 발생했을 수 있습니다. IE는 아마도 GMT 만 기대할 것입니다.


답변

“만료”대신 Max-Age = -1을 사용하십시오. 구문이 짧고 까다 롭지 않으며 Max-Age가 Expires보다 우선합니다.


답변

GlassFish Jersey JAX-RS 구현의 경우 일반적인 방법으로 모든 공통 매개 변수를 설명하여이 문제를 해결했습니다. name (= “name”), path (= “/”) 및 domain (= null) 중 적어도 3 개의 매개 변수가 같아야합니다.

public static NewCookie createDomainCookie(String value, int maxAgeInMinutes) {
    ZonedDateTime time = ZonedDateTime.now().plusMinutes(maxAgeInMinutes);
    Date expiry = time.toInstant().toEpochMilli();
    NewCookie newCookie = new NewCookie("name", value, "/", null, Cookie.DEFAULT_VERSION,null, maxAgeInMinutes*60, expiry, false, false);
    return newCookie;
}

쿠키를 설정하는 일반적인 방법을 사용하십시오.

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie(token, 60);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

쿠키를 삭제하려면 :

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie("", 0);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();


답변