◀ 8.

djangoにおけるcookieの値の設定と取得

▶
この記事の要点
  • 設定はレスポンスオブジェクトの response.set_cookie('key', 'value', max_age=秒)
  • 取得はリクエストの request.COOKIES.get('key')(値は常に文字列)
  • 削除は response.delete_cookie('key')
  • max_age を省略するとブラウザを閉じるまでのセッション Cookie になる
  • 改ざんを防ぎたい値は set_signed_cookie / get_signed_cookie、秘密情報はそもそも Cookie に入れずセッションを使う

Cookie の設定(set_cookie)

Django では、Cookie はレスポンスに付けて返します。ビューで作ったレスポンスオブジェクトの set_cookie() を呼び、そのレスポンスを return します。

from django.http import HttpResponse

def set_flag(request):
    response = HttpResponse("Cookie Set")
    response.set_cookie('flag', '600')
    return response

テンプレートを使う場合も、render() の戻り値がレスポンスなので同じように書けます。

from django.shortcuts import render, redirect

def index(request):
    response = render(request, 'app/index.html', {'title': 'トップ'})
    response.set_cookie('last_visit', '2026-10-03', max_age=60 * 60 * 24 * 30)
    return response

def login_done(request):
    response = redirect('dashboard')
    response.set_cookie('theme', 'dark')
    return response

主な引数

引数意味既定値
key / valueCookie の名前と値(文字列)—
max_age有効期限を秒単位で指定。Django 4.1 以降は timedelta も可None(ブラウザを閉じるまで)
expires有効期限を日時で指定(max_age とどちらか一方でよい)None
pathCookie を送信するパス'/'
domain送信先ドメイン。サブドメイン間で共有するなら '.example.com'None(現在のホストのみ)
secureTrue で HTTPS 通信時だけ送信False
httponlyTrue で JavaScript(document.cookie)から読めなくするFalse
samesite'Lax' / 'Strict' / 'None'。他サイトからのリクエストに付けるかどうかNone(属性なし。多くのブラウザは Lax として扱う)

max_age には秒単位で Cookie の期限を指定します。指定しなかった場合はブラウザを閉じるまで Cookie が保持されます(セッション Cookie)。実運用では次のように属性を明示するのがおすすめです。

from datetime import timedelta

response.set_cookie(
    'flag', '600',
    max_age=timedelta(days=7),   # Django 4.1 未満なら 60 * 60 * 24 * 7
    secure=True,
    httponly=True,
    samesite='Lax',
)

Cookie の取得(request.COOKIES)

取得は以下のようにキー名を指定すればよいです。request.COOKIES は辞書なので、存在しない場合に備えて get() を使います。

def show_flag(request):
    flag = request.COOKIES.get('flag')             # なければ None
    count = int(request.COOKIES.get('count', '0'))  # 既定値を指定して数値化
    return HttpResponse(f"flag={flag}, count={count}")

request.COOKIES['flag'] と角かっこで書くと、Cookie がないときに KeyError になります。また値は常に文字列なので、数値として使う場合は変換が必要です。Cookie はユーザーが自由に書き換えられるため、int() が失敗する可能性も考慮して例外処理を入れておくと安全です。

テンプレートからは {{ request.COOKIES.flag }} で参照できます(django.template.context_processors.request が有効な場合。startproject の既定設定では有効)。

Cookie の削除(delete_cookie)

def clear_flag(request):
    response = HttpResponse("Cookie Deleted")
    response.delete_cookie('flag')
    return response

設定時に path や domain を指定した Cookie は、削除時にも同じ値を指定しないと消えません(例: delete_cookie('flag', path='/app/', domain='.example.com'))。

署名付き Cookie(改ざん検知)

通常の Cookie はブラウザの開発者ツールで簡単に書き換えられます。値が改ざんされていないことを確認したい場合は署名付き Cookie を使います。署名には settings.py の SECRET_KEY が使われます。

from django.core.signing import BadSignature

# 設定
response.set_signed_cookie('user_pref', 'compact', salt='pref', max_age=3600)

# 取得
try:
    pref = request.get_signed_cookie('user_pref', salt='pref', max_age=3600)
except (KeyError, BadSignature):
    pref = 'default'

# default を渡すと、Cookie がない・署名が不正な場合に例外ではなく既定値を返す
pref = request.get_signed_cookie('user_pref', default='default', salt='pref')

署名は「改ざんされていないこと」を保証するだけで、値は暗号化されず読めます。パスワードや個人情報など見られて困る値は Cookie に入れず、request.session(サーバー側に保存されるセッション)を使ってください。

よくある落とし穴

  • 同じリクエスト内では読めない: set_cookie はレスポンスに Set-Cookie ヘッダを付けるだけなので、設定した値が request.COOKIES に入るのはブラウザが次にリクエストしてきたとき
  • レスポンスを return し忘れる: set_cookie したレスポンスとは別のレスポンスを返すと Cookie は付かない
  • サイズ制限: 1 つの Cookie はおよそ 4KB までが目安。大きなデータはセッションや DB に保存し、Cookie には ID だけを入れる
  • 日本語などの値: ブラウザ間の扱いの差を避けるため、ASCII 以外の文字は urllib.parse.quote でエンコードしてから保存し、取得時に unquote するのが無難
  • samesite='None' には secure=True が必須: 主要ブラウザは Secure のない SameSite=None の Cookie を拒否する

確認方法

  • ブラウザの開発者ツール(Chrome なら「Application」→「Cookies」)で、名前・値・有効期限・属性を確認する
  • 開発者ツールの「Network」タブで、レスポンスヘッダに Set-Cookie が含まれているか確認する
  • コマンドでは curl -i http://127.0.0.1:8000/set_flag/ でヘッダを確認できる
  • テストコードでは Django のテストクライアントの response.cookies['flag'].value で検証できる

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. クラスベースビュー(主流)の作り方とviewの分割
  2. 関数ベースビューの作り方とviewの分割
  3. URLディスパッチャー(ルーティング処理)
  4. GETとPOSTパラメータ受け取り
  5. クラスベースビューでGET/POSTリクエストの受け取り方
  6. クラスベースビューでテンプレートに値を渡す方法
  7. ビューでリダイレクト
  8. cookieの値の設定と取得
  9. HTTPステータスコードの返し方