Djangoの署名付きCookieをテストする方法

この記事のDjangoのバージョンは4.2になります。

署名付きCookieの設定

Djangoで署名付きCookieをセットする際は、set_signed_cookieメソッドを使用します。

from django.http import HttpResponse

def my_view(request):
    response = HttpResponse("Hello, World!")
    response.set_signed_cookie('user_preference', 'dark_mode', salt='my_salt')
    return response

署名付きCookieのテスト方法

署名付きCookieが正しくセットされているかをテストしたい場合、django.core.signing.get_cookie_signerを使用することができます。

実際の値は django.core.signing.get_cookie_signer の返り値である django.core.signing.Signerunsign メソッドを利用します。

テストコードの例

from django.test import TestCase, RequestFactory
from django.core.signing import get_cookie_signer, BadSignature
from myapp.views import my_view

class SignedCookieTestCase(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
    
    def test_signed_cookie_is_set_correctly(self):
        # ビューを呼び出してレスポンスを取得
        request = self.factory.get('/')
        response = my_view(request)
        
        # Cookieが設定されているかを確認
        self.assertIn('user_preference', response.cookies)
        
        # 署名付きCookieの値を検証
        cookie_value = response.cookies['user_preference'].value
        signer = get_cookie_signer(salt='my_salt')
        
        # 署名を検証して元の値を取得
        try:
            original_value = signer.unsign(cookie_value)
            self.assertEqual(original_value, 'dark_mode')
        except BadSignature:
            self.fail("Cookie signature is invalid")

重要なポイント

saltの指定は必須です。get_cookie_signerを使用する際は、set_signed_cookieで使用したのと同じsaltを指定してください。

# set_signed_cookieで使用したsaltと同じものを指定
signer = get_cookie_signer(salt='my_salt')

調べた理由

django.http.HttpRequest.get_signed_cookieユニットテストで利用したかったのですが、うまく使うことができませんでした。

django.http.HttpRequest.get_signed_cookie のコードを見て、上記の実装方法があることを理解し、ユニットテストで利用しています。

まとめ

  • set_signed_cookieで署名付きCookieを設定
  • テスト時はget_cookie_signerを使って署名を検証
  • saltの指定を忘れずに