Django change CSRF cookie secure flag according to url scheme

這項需求簡單說就是:如果是用 http url 的話,cookie 中的 CSRF 就不帶 secure 屬性,https 的話就加上。

我的想法是動態去更改 settings.CSRF_COOKIE_SECURE 的值,從 django.middleware.csrf.CsrfViewMiddlewareprocess_response 可以看到,它是直接抓這個值來判斷,所以如果我在這之前去做修改的話,就可以得到不同的 secure 屬性。

如果可以修改 Django source code 話其實可以到 django.middleware.csrf.CsrfViewMiddleware 修改 process_response,根據 request.is_secure 來判斷,如果是 httpsrequest.is_secure 就會是 True,反之亦然。不過畢竟這不是一個長久之計,所以還是自己另外寫一個 middleware,如下:

from django.conf import settings


class CsrfSecureMiddleware(object):  
    def process_request(self, request):
        settings.CSRF_COOKIE_SECURE = request.is_secure

[middleware 有好幾個 hook point],預防萬一,所以還是在一開始接到 request 的地方,也就是 process_request 的時候就做判斷,修改 CSRF_COOKIE_SECURE 的值。

middleware 弄完後,在 MIDDLEWARE_CLASSES 裡放在 django.middleware.csrf.CsrfViewMiddleware 之前就可以了,如果沒有使用這個 middleware,而是用 CSRF view decorator 的方式來做的話,在 MIDDLEWARE_CLASSES 放的位置就沒什麼差。

carlcarl

Read more posts by this author.