2013-09-23 4 views
4

Django 앱의 프런트 엔드 캐시로 varnish를 사용하고 있습니다. VCL 구성과 관련해서는 모두 잘 작동합니다. 내가 가진 문제는 사용자가 로그 아웃 한 후 csrftoken 쿠키가 삭제되지 않고 그 다음부터 바니시에 HIT 대신 MISS 응답이 있다는 것입니다.장고는 로그 아웃 후 csrftoken을 삭제할 수 없습니다.

backend default { 
    .host = "127.0.0.1"; 
    .port = "8000"; 
} 

sub vcl_recv { 
    set req.grace = 15s; 

    if (req.http.Cookie) { 
     set req.http.Cookie = regsuball(req.http.Cookie, "(^|;) *__utm.=[^;]+;? *", "\1"); # removes all cookies named __utm? (utma, utmb...) - tracking thing 
    } 

    # unless sessionid/csrftoken is in the request, don't pass ANY cookies (referral_source, utm, etc) 
    if (req.request == "GET" && (req.url ~ "^/static" || (req.http.cookie !~ "flash_sessionid" && req.http.cookie !~ "csrftoken"))) { 
     remove req.http.Cookie; 
    } 

    # normalize accept-encoding to account for different browsers 
    # see: https://www.varnish-cache.org/trac/wiki/VCLExampleNormalizeAcceptEncoding 
    if (req.http.Accept-Encoding) { 
     if (req.http.Accept-Encoding ~ "gzip") { 
      set req.http.Accept-Encoding = "gzip"; 
     } elsif (req.http.Accept-Encoding ~ "deflate") { 
      set req.http.Accept-Encoding = "deflate"; 
     } else { 
      # unknown algorithm 
      remove req.http.Accept-Encoding; 
     } 
    } 
} 

sub vcl_fetch { 
    set beresp.ttl = 300s; 
    set beresp.grace = 15s; 

    # static files always cached 
    if (req.url ~ "^/static") { 
     unset beresp.http.set-cookie; 
     return (deliver); 
    } 

    # pass through for anything with a session/csrftoken set 
    if (beresp.http.set-cookie ~ "flash_sessionid" || beresp.http.set-cookie ~ "csrftoken") { 
     return (hit_for_pass); 
    } else { 
     return (deliver); 
    } 
} 

sub vcl_deliver { 
    # Add a header to indicate a cache HIT/MISS 
    if (obj.hits > 0) { 
     set resp.http.X-Cache = "HIT"; 
    } else { 
     set resp.http.X-Cache = "MISS"; 
    } 
    return (deliver); 
} 
: 사용자가 완전성에 대한 로그 아웃 페이지를

Response Headers 
Age:0 
Cache-Control:max-age=600 
Connection:keep-alive 
Content-Language:en 
Content-Type:text/html; charset=utf-8 
Date:Mon, 23 Sep 2013 09:20:43 GMT 
Expires:Mon, 23 Sep 2013 09:30:43 GMT 
P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT" 
Server:nginx/1.4.1 
Set-Cookie:sessionid=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/ 
Set-Cookie:csrftoken=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/ 
Transfer-Encoding:chunked 
Vary:Cookie, Accept-Language, Host 
Via:1.1 varnish 
X-Cache:MISS 
X-Varnish:1950616479 

default.vcl 충돌 후 약간의 관련 질문에 내가이 로그 아웃보기

def logout_view(request): 
    response = render_to_response('registration/logout.html', {}, context_instance=RequestContext(request)) 

    if request.user.is_authenticated(): 
     logout(request) 

     if request.GET.get('next', False): 
      response = HttpResponseRedirect(next) 

    response.delete_cookie('sessionid') 
    response.delete_cookie('csrftoken') 
    return response 

이 응답 헤더가 유래 여기 읽은 후

응답 헤더에서 Django가 쿠키 값을 과거 날짜로 설정하는 것을 봅니다. 그러나 csrftoken 쿠키 다음 요청시까지 지속됩니다.

또한 'django.middleware.csrf.CsrfViewMiddleware'미들웨어를 제거하려고했지만 쿠키가 여전히 존재합니다.

답변

1

당신은 다음과 같이 vcl_fetch을 편집하여 문제를 해결할 수 :

sub vcl_fetch { 
    # pass through for anything with a session/csrftoken set 
    if (beresp.http.set-cookie ~ "flash_sessionid" || beresp.http.set-cookie ~ "csrftoken" || beresp.http.set-cookie ~ "sessionid") { 
     return (hit_for_pass); 
    } else { 
     return (deliver); 
    } 
} 

당신은뿐만 아니라 Set-Cookie:sessionid 확인하고이 방법.

바니시는 beresp.http.set-cookie을 사용할 때 첫 번째 세트 쿠키 헤더 만 보게되므로 바니시는 hit_for_pass 대신 vcl_deliver를 반환합니다.

추가 정보는 vmod_header을 참조하십시오.