セッションの使い方
Djangoは匿名セッションを完全にサポートします。 セッションフレームワークを使用すると、サイト訪問者ごとに任意のデータを保存および取得できます。 サーバー側にデータを保存し、Cookieの送受信を抽象化します。 Cookieには、データ自体ではなくセッションIDが含まれます( Cookieベースのバックエンドを使用している場合を除く)。
セッションの有効化
セッションは、ミドルウェアの一部を介して実装されます。
セッション機能を有効にするには、次の手順を実行します。
- :setting: `MIDDLEWARE` 設定を編集し、
'django.contrib.sessions.middleware.SessionMiddleware'
が含まれていることを確認します。django-admin startproject
によって作成されたデフォルトのsettings.py
では、SessionMiddleware
がアクティブになっています。
セッションを使用したくない場合は、:setting: `MIDDLEWARE` および'django.contrib.sessions'
からSessionMiddleware
行を:settingから削除することもできます。 : `INSTALLED_APPS` 。 それはあなたに少しのオーバーヘッドを節約するでしょう。
セッションエンジンの構成
デフォルトでは、Djangoはセッションをデータベースに保存します(モデルdjango.contrib.sessions.models.Session
を使用)。 これは便利ですが、一部のセットアップではセッションデータを他の場所に保存する方が高速であるため、セッションデータをファイルシステムまたはキャッシュに保存するようにDjangoを構成できます。
データベースに裏打ちされたセッションの使用
データベースに基づくセッションを使用する場合は、'django.contrib.sessions'
を:setting: `INSTALLED_APPS` 設定に追加する必要があります。
インストールを構成したら、manage.py migrate
を実行して、セッションデータを格納する単一のデータベーステーブルをインストールします。
キャッシュされたセッションの使用
パフォーマンスを向上させるために、キャッシュベースのセッションバックエンドを使用することをお勧めします。
Djangoのキャッシュシステムを使用してセッションデータを保存するには、最初にキャッシュを構成したことを確認する必要があります。 詳細については、キャッシュドキュメントを参照してください。
警告
Memcachedキャッシュバックエンドを使用している場合にのみ、キャッシュベースのセッションを使用する必要があります。 ローカルメモリキャッシュバックエンドは、適切な選択を行うのに十分な長さのデータを保持しません。ファイルまたはデータベースキャッシュバックエンドを介してすべてを送信するよりも、ファイルまたはデータベースセッションを直接使用する方が高速です。 さらに、ローカルメモリキャッシュバックエンドはマルチプロセスセーフではないため、本番環境にはおそらく適切な選択ではありません。
:setting: `CACHES` で複数のキャッシュが定義されている場合、Djangoはデフォルトのキャッシュを使用します。 別のキャッシュを使用するには、:setting: `SESSION_CACHE_ALIAS` をそのキャッシュの名前に設定します。
キャッシュを構成したら、データをキャッシュに保存する方法について2つの選択肢があります。
- 単純なキャッシュセッションストアの場合は、:setting: `SESSION_ENGINE` を
"django.contrib.sessions.backends.cache"
に設定します。 セッションデータはキャッシュに直接保存されます。 ただし、セッションデータは永続的でない場合があります。キャッシュがいっぱいになった場合、またはキャッシュサーバーが再起動された場合、キャッシュされたデータは削除される可能性があります。 - 永続的なキャッシュデータの場合は、:setting: `SESSION_ENGINE` を
"django.contrib.sessions.backends.cached_db"
に設定します。 これはライトスルーキャッシュを使用します–キャッシュへのすべての書き込みはデータベースにも書き込まれます。 セッション読み取りは、データがまだキャッシュにない場合にのみデータベースを使用します。
どちらのセッションストアも非常に高速ですが、永続性を無視するため、単純なキャッシュの方が高速です。 ほとんどの場合、cached_db
バックエンドは十分に高速ですが、パフォーマンスの最後のビットが必要で、セッションデータを随時消去できる場合は、cache
バックエンドはあなたのために。
cached_db
セッションバックエンドを使用する場合は、データベースバックアップセッションを使用するための構成手順にも従う必要があります。
ファイルベースのセッションの使用
ファイルベースのセッションを使用するには、:setting: `SESSION_ENGINE` 設定を"django.contrib.sessions.backends.file"
に設定します。
:setting: `SESSION_FILE_PATH` 設定(デフォルトではtempfile.gettempdir()
、おそらく/tmp
からの出力)を設定して、Djangoがセッションファイルを保存する場所を制御することもできます。 Webサーバーにこの場所の読み取りと書き込みのアクセス許可があることを必ず確認してください。
ビューでのセッションの使用
SessionMiddleware
がアクティブ化されると、各 HttpRequest オブジェクト(Djangoビュー関数の最初の引数)には、辞書のようなオブジェクトであるsession
属性があります。
ビューの任意の場所で読み取りと書き込みを行うことができますrequest.session
。 複数回編集できます。
- class backends.base.SessionBase
これは、すべてのセッションオブジェクトの基本クラスです。 次の標準的な辞書メソッドがあります。
- __getitem__(key)
例:
fav_color = request.session['fav_color']
- __setitem__(key, value)
例:
request.session['fav_color'] = 'blue'
- __delitem__(key)
例:
del request.session['fav_color']
。 指定されたkey
がまだセッションにない場合、これによりKeyError
が発生します。
- __contains__(key)
例:
'fav_color' in request.session
- get(key, default=None)
例:
fav_color = request.session.get('fav_color', 'red')
- pop(key, default=__not_given)
例:
fav_color = request.session.pop('fav_color', 'blue')
- keys()
- items()
- setdefault()
- clear()
また、次のメソッドもあります。
- flush()
現在のセッションデータをセッションから削除し、セッションCookieを削除します。 これは、ユーザーのブラウザーから前のセッションデータに再度アクセスできないようにする場合に使用されます(たとえば、 django.contrib.auth.logout()関数がそれを呼び出します)。
- set_test_cookie()
ユーザーのブラウザがCookieをサポートしているかどうかを判断するためのテストCookieを設定します。 Cookieの動作方法により、ユーザーが次のページをリクエストするまで、これをテストすることはできません。 詳細については、以下のテストCookieの設定を参照してください。
- test_cookie_worked()
ユーザーのブラウザがテストCookieを受け入れたかどうかに応じて、
True
またはFalse
のいずれかを返します。 Cookieの動作方法により、以前の別のページのリクエストでset_test_cookie()
を呼び出す必要があります。 詳細については、以下のテストCookieの設定を参照してください。
- delete_test_cookie()
テストCookieを削除します。 これを使用して、自分の後でクリーンアップします。
- get_session_cookie_age()
セッションCookieの経過時間を秒単位で返します。 デフォルトは:setting: `SESSION_COOKIE_AGE` です。
- set_expiry(value)
セッションの有効期限を設定します。 いくつかの異なる値を渡すことができます。
value
が整数の場合、セッションは、何秒も非アクティブになった後に期限切れになります。 たとえば、request.session.set_expiry(300)
を呼び出すと、セッションは5分で期限切れになります。value
がdatetime
またはtimedelta
オブジェクトの場合、セッションはその特定の日時に期限切れになります。datetime
およびtimedelta
の値は、 PickleSerializer を使用している場合にのみシリアル化できることに注意してください。value
が0
の場合、ユーザーのWebブラウザーを閉じると、ユーザーのセッションCookieは期限切れになります。value
がNone
の場合、セッションはグローバルセッション有効期限ポリシーの使用に戻ります。
セッションの読み取りは、有効期限の目的でのアクティビティとは見なされません。 セッションの有効期限は、セッションが最後に変更されたから計算されます。
- get_expiry_age()
このセッションが期限切れになるまでの秒数を返します。 カスタム有効期限のないセッション(またはブラウザの終了時に有効期限が切れるように設定されているセッション)の場合、これは:setting: `SESSION_COOKIE_AGE` と等しくなります。
この関数は、2つのオプションのキーワード引数を受け入れます。
modification
:datetime
オブジェクトとしての、セッションの最後の変更。 デフォルトは現在の時刻です。expiry
:datetime
オブジェクト、int
(秒単位)、またはNone
としてのセッションの有効期限情報。 デフォルトは、 set_expiry()(存在する場合)またはNone
によってセッションに格納された値です。
- get_expiry_date()
このセッションの有効期限が切れる日付を返します。 カスタム有効期限のないセッション(またはブラウザの終了時に有効期限が切れるように設定されているセッション)の場合、これは現在から:setting: `SESSION_COOKIE_AGE` 秒の日付に等しくなります。
この関数は、 get_expiry_age()と同じキーワード引数を受け入れます。
- get_expire_at_browser_close()
ユーザーのWebブラウザーを閉じたときにユーザーのセッションCookieが期限切れになるかどうかに応じて、
True
またはFalse
のいずれかを返します。
- clear_expired()
期限切れのセッションをセッションストアから削除します。 このクラスメソッドは、:djadmin: `clearsessions` によって呼び出されます。
- cycle_key()
現在のセッションデータを保持しながら、新しいセッションキーを作成します。 django.contrib.auth.login()は、このメソッドを呼び出して、セッション固定を軽減します。
セッションのシリアル化
デフォルトでは、DjangoはJSONを使用してセッションデータをシリアル化します。 :setting: `SESSION_SERIALIZER` 設定を使用して、セッションのシリアル化形式をカスタマイズできます。 独自のシリアライザーを作成するで説明されている警告があっても、特にCookieバックエンドを使用している場合は、JSONシリアル化を使用することを強くお勧めします。
たとえば、pickle
を使用してセッションデータをシリアル化する場合の攻撃シナリオを次に示します。 署名付きCookieセッションバックエンドを使用していて:setting: `SECRET_KEY` が攻撃者に知られている場合(Djangoには、リークの原因となる固有の脆弱性はありません) )、攻撃者はセッションに文字列を挿入する可能性があり、選択を解除すると、サーバー上で任意のコードが実行されます。 そうするための技術は単純で、インターネット上で簡単に利用できます。 Cookieセッションストレージは、改ざんを防ぐためにCookieに保存されたデータに署名しますが、:setting: `SECRET_KEY` リークは、すぐにリモートコード実行の脆弱性にエスカレートします。
バンドルされたシリアライザー
- class serializers.JSONSerializer
django.core.signing のJSONシリアライザーのラッパー。 基本的なデータ型のみをシリアル化できます。
さらに、JSONは文字列キーのみをサポートするため、
request.session
で非文字列キーを使用すると期待どおりに機能しないことに注意してください。>>> # initial assignment >>> request.session[0] = 'bar' >>> # subsequent requests following serialization & deserialization >>> # of session data >>> request.session[0] # KeyError >>> request.session['0'] 'bar'
同様に、
'\xd9'
(UnicodeDecodeError
を発生させる)のような非UTF8バイトなど、JSONでエンコードできないデータは保存できません。JSONシリアル化の制限の詳細については、独自のシリアライザーを作成するセクションを参照してください。
- class serializers.PickleSerializer
- 任意のPythonオブジェクトをサポートしますが、前述のように、:setting: `SECRET_KEY` が攻撃者に知られると、リモートでコードが実行される脆弱性が発生する可能性があります。
独自のシリアライザーを作成する
PickleSerializer とは異なり、 JSONSerializer は任意のPythonデータ型を処理できないことに注意してください。 よくあることですが、利便性とセキュリティの間にはトレードオフがあります。 datetime
やDecimal
などのより高度なデータ型をJSONでバックアップされたセッションに保存する場合は、カスタムシリアライザーを作成する(またはそのような値をJSONシリアル化可能オブジェクトに変換してから保存する)必要があります。 request.session
)。 これらの値のシリアル化は多くの場合簡単ですが( DjangoJSONEncoder が役立つ場合があります)、入力したものと同じものを確実に取り戻すことができるデコーダーを作成する方が脆弱です。 たとえば、実際にはdatetime
に選択されたのと同じ形式の文字列であるdatetime
を返すリスクがあります。
シリアライザークラスは、セッションデータのディクショナリをそれぞれシリアル化および逆シリアル化するために、dumps(self, obj)
およびloads(self, data)
の2つのメソッドを実装する必要があります。
セッションオブジェクトのガイドライン
request.session
の辞書キーとして通常のPython文字列を使用します。 これは、厳格なルールというよりは慣例です。- アンダースコアで始まるセッションディクショナリキーは、Djangoによる内部使用のために予約されています。
request.session
を新しいオブジェクトでオーバーライドしたり、その属性にアクセスしたり設定したりしないでください。 Python辞書のように使用してください。
例
この単純なビューは、ユーザーがコメントを投稿した後、has_commented
変数をTrue
に設定します。 ユーザーがコメントを複数回投稿することはできません。
def post_comment(request, new_comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
この単純なビューは、サイトの「メンバー」にログインします。
def login(request):
m = Member.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
…そして、上記のlogin()
によると、これはメンバーをログアウトします。
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
標準の django.contrib.auth.logout()関数は、不注意によるデータ漏洩を防ぐために、実際にはこれよりも少し多くのことを行います。 request.session
の flush()メソッドを呼び出します。 この例は、完全なlogout()
実装としてではなく、セッションオブジェクトを操作する方法のデモンストレーションとして使用しています。
ビュー外でのセッションの使用
ノート
このセクションの例では、SessionStore
オブジェクトをdjango.contrib.sessions.backends.db
バックエンドから直接インポートします。 独自のコードでは、次のように、:setting: `SESSION_ENGINE` で指定されたセッションエンジンからSessionStore
をインポートすることを検討する必要があります。
>>> from importlib import import_module
>>> from django.conf import settings
>>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
ビューの外部でセッションデータを操作するためのAPIを使用できます。
>>> from django.contrib.sessions.backends.db import SessionStore
>>> s = SessionStore()
>>> # stored as seconds since epoch since datetimes are not serializable in JSON.
>>> s['last_login'] = 1376587691
>>> s.create()
>>> s.session_key
'2b1189a188b44ad18c35e113ac6ceead'
>>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
>>> s['last_login']
1376587691
SessionStore.create()
は、新しいセッションを作成するように設計されています(つまり、 セッションストアからロードされておらず、session_key=None
が付いているもの。 save()
は、既存のセッションを保存するように設計されています(つまり、 セッションストアからロードされたもの)。 新しいセッションでsave()
を呼び出すことも機能する可能性がありますが、既存のセッションと衝突するsession_key
を生成する可能性はわずかです。 create()
はsave()
を呼び出し、未使用のsession_key
が生成されるまでループします。
django.contrib.sessions.backends.db
バックエンドを使用している場合、各セッションは通常のDjangoモデルです。 Session
モデルは、django/contrib/sessions/models.py
で定義されています。 これは通常のモデルであるため、通常のDjangoデータベースAPIを使用してセッションにアクセスできます。
>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)
セッションディクショナリを取得するには、 get_decoded()を呼び出す必要があることに注意してください。 辞書はエンコードされた形式で保存されるため、これが必要です。
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
セッションが保存されるとき
デフォルトでは、Djangoはセッションが変更された場合、つまりディクショナリ値のいずれかが割り当てまたは削除された場合にのみセッションデータベースに保存します。
# Session is modified.
request.session['foo'] = 'bar'
# Session is modified.
del request.session['foo']
# Session is modified.
request.session['foo'] = {}
# Gotcha: Session is NOT modified, because this alters
# request.session['foo'] instead of request.session.
request.session['foo']['bar'] = 'baz'
上記の例の最後のケースでは、セッションオブジェクトにmodified
属性を設定することで、セッションオブジェクトが変更されたことを明示的に伝えることができます。
request.session.modified = True
このデフォルトの動作を変更するには、:setting: `SESSION_SAVE_EVERY_REQUEST` 設定をTrue
に設定します。 True
に設定すると、Djangoはすべてのリクエストでセッションをデータベースに保存します。
セッションCookieは、セッションが作成または変更された場合にのみ送信されることに注意してください。 :setting: `SESSION_SAVE_EVERY_REQUEST` がTrue
の場合、セッションCookieはすべてのリクエストで送信されます。
同様に、セッションCookieのexpires
部分は、セッションCookieが送信されるたびに更新されます。
応答のステータスコードが500の場合、セッションは保存されません。
ブラウザの長さのセッションと 永続的なセッション
セッションフレームワークがブラウザの長さのセッションを使用するかどうかを制御できます。 :setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE` 設定の永続セッション。
デフォルトでは、:setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE` はFalse
に設定されています。これは、セッションCookieが:setting:` SESSION_COOKIE_AGE` [ X195X]。 ブラウザを開くたびにログインする必要がないようにする場合は、これを使用します。
:setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE` がTrue
に設定されている場合、Djangoはブラウザの長さのCookie(ユーザーがブラウザを閉じるとすぐに期限切れになるCookie)を使用します。 ブラウザを開くたびにログインする必要がある場合は、これを使用します。
この設定はグローバルデフォルトであり、ビューでのセッションの使用で前述したように、request.session
の set_expiry()メソッドを明示的に呼び出すことにより、セッションごとのレベルで上書きできます。 ]。
ノート
一部のブラウザ(Chromeなど)は、ユーザーがブラウザを閉じて再度開いた後もセッションの閲覧を続行できるようにする設定を提供します。 場合によっては、これが:setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE` 設定に干渉し、ブラウザを閉じたときにセッションが期限切れになるのを防ぐことができます。 :setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE` 設定が有効になっているDjangoアプリケーションをテストするときは、このことに注意してください。
セッションストアのクリア
ユーザーがWebサイトで新しいセッションを作成すると、セッションデータがセッションストアに蓄積される可能性があります。 データベースバックエンドを使用している場合、django_session
データベーステーブルが大きくなります。 ファイルバックエンドを使用している場合、一時ディレクトリに含まれるファイルの数は増加します。
この問題を理解するには、データベースバックエンドで何が起こるかを考えてください。 ユーザーがログインすると、Djangoはdjango_session
データベーステーブルに行を追加します。 Djangoは、セッションデータが変更されるたびにこの行を更新します。 ユーザーが手動でログアウトすると、Djangoは行を削除します。 ただし、ユーザーがログアウトしない場合、行が削除されることはありません。 同様のプロセスがファイルバックエンドでも発生します。
Djangoは期限切れのセッションの自動パージを提供しません。 したがって、期限切れのセッションを定期的に削除するのはあなたの仕事です。 Djangoは、この目的のためにクリーンアップ管理コマンドを提供します::djadmin: `clearsessions` 。 このコマンドは、たとえば毎日のcronジョブとして定期的に呼び出すことをお勧めします。
キャッシュは古いデータを自動的に削除するため、キャッシュバックエンドはこの問題に対して脆弱ではないことに注意してください。 セッションデータはユーザーのブラウザによって保存されるため、Cookieバックエンドも同様です。
設定
いくつかの Django設定を使用すると、セッションの動作を制御できます。
- :setting: `SESSION_CACHE_ALIAS`
- :setting: `SESSION_COOKIE_AGE`
- :setting: `SESSION_COOKIE_DOMAIN`
- :setting: `SESSION_COOKIE_HTTPONLY`
- :setting: `SESSION_COOKIE_NAME`
- :setting: `SESSION_COOKIE_PATH`
- :setting: `SESSION_COOKIE_SAMESITE`
- :setting: `SESSION_COOKIE_SECURE`
- :setting: `SESSION_ENGINE`
- :setting: `SESSION_EXPIRE_AT_BROWSER_CLOSE`
- :setting: `SESSION_FILE_PATH`
- :setting: `SESSION_SAVE_EVERY_REQUEST`
- :setting: `SESSION_SERIALIZER`
セッションセキュリティ
サイト内のサブドメインは、ドメイン全体のクライアントにCookieを設定できます。 これにより、信頼できるユーザーによって制御されていないサブドメインからのCookieが許可されている場合、セッション固定が可能になります。
たとえば、攻撃者はgood.example.com
にログインして、自分のアカウントの有効なセッションを取得する可能性があります。 攻撃者がbad.example.com
を制御している場合、サブドメインは*.example.com
にCookieを設定することが許可されているため、攻撃者はそれを使用してセッションキーを送信できます。 good.example.com
にアクセスすると、攻撃者としてログインし、機密性の高い個人データを誤って入力する可能性があります(例: クレジットカード情報)を攻撃者のアカウントに入力します。
別の攻撃の可能性は、good.example.com
が:setting: `SESSION_COOKIE_DOMAIN` を"example.com"
に設定した場合です。これにより、そのサイトからのセッションCookieがbad.example.com
に送信されます。 ]。
技術的な詳細
- セッションディクショナリは、 JSONSerializer を使用する場合は
json
のシリアル化可能な値を受け入れ、 PickleSerializer を使用する場合は任意の選択可能なPythonオブジェクトを受け入れます。 詳細については、pickle
モジュールを参照してください。 - セッションデータは、
django_session
という名前のデータベーステーブルに保存されます。 - Djangoは必要な場合にのみCookieを送信します。 セッションデータを設定しない場合、セッションCookieは送信されません。
SessionStoreオブジェクト
内部でセッションを操作する場合、Djangoは対応するセッションエンジンのセッションストアオブジェクトを使用します。 慣例により、セッションストアオブジェクトクラスはSessionStore
という名前で、:setting: `SESSION_ENGINE` で指定されたモジュールに配置されます。
Djangoで利用可能なすべてのSessionStore
クラスは、 SessionBase を継承し、データ操作メソッドを実装します。
exists()
create()
save()
delete()
load()
clear_expired()
カスタムセッションエンジンを構築したり、既存のセッションエンジンをカスタマイズしたりするには、 SessionBase またはその他の既存のSessionStore
クラスを継承する新しいクラスを作成できます。
セッションエンジンを拡張することはできますが、データベースでバックアップされたセッションエンジンを使用して拡張するには、通常、追加の作業が必要です(詳細については次のセクションを参照してください)。
データベースに裏打ちされたセッションエンジンの拡張
Djangoに含まれているもの(つまりdb
とcached_db
)に基づいて構築されたカスタムデータベースバックアップセッションエンジンの作成は、 AbstractBaseSession とSessionStore
のいずれかを継承することで実行できます。クラス。
AbstractBaseSession
とBaseSessionManager
はdjango.contrib.sessions.base_session
からインポートできるため、:setting: `INSTALLED_APPS` にdjango.contrib.sessions
を含めずにインポートできます。
- class base_session.AbstractBaseSession
抽象ベースセッションモデル。
- session_key
主キー。 フィールド自体には最大40文字を含めることができます。 現在の実装では、32文字の文字列(数字と小文字のASCII文字のランダムなシーケンス)が生成されます。
- session_data
エンコードおよびシリアル化されたセッションディクショナリを含む文字列。
- expire_date
セッションの有効期限が切れる日時を指定します。
期限切れのセッションはユーザーが利用できませんが、:djadmin: `clearsessions` 管理コマンドが実行されるまでデータベースに保存される可能性があります。
- classmethod get_session_store_class()
このセッションモデルで使用されるセッションストアクラスを返します。
- get_decoded()
デコードされたセッションデータを返します。
デコードは、セッションストアクラスによって実行されます。
BaseSessionManager をサブクラス化して、モデルマネージャーをカスタマイズすることもできます。
- class base_session.BaseSessionManager
- encode(session_dict)
文字列としてシリアル化およびエンコードされた、指定されたセッションディクショナリを返します。
エンコードは、モデルクラスに関連付けられたセッションストアクラスによって実行されます。
- save(session_key, session_dict, expire_date)
指定されたセッションキーのセッションデータを保存するか、データが空の場合はセッションを削除します。
SessionStore
クラスのカスタマイズは、以下で説明するメソッドとプロパティをオーバーライドすることで実現されます。
- class backends.db.SessionStore
データベースに裏打ちされたセッションストアを実装します。
- classmethod get_model_class()
必要に応じて、このメソッドをオーバーライドして、カスタムセッションモデルを返します。
- create_model_instance(data)
現在のセッション状態を表すセッションモデルオブジェクトの新しいインスタンスを返します。
このメソッドをオーバーライドすると、データベースに保存する前にセッションモデルデータを変更することができます。
- class backends.cached_db.SessionStore
- キャッシュされたデータベースに裏打ちされたセッションストアを実装します。
- cache_key_prefix
- キャッシュキー文字列を構築するためにセッションキーに追加されるプレフィックス。
例
以下の例は、アカウントIDを格納するための追加のデータベース列を含むカスタムデータベースバックアップセッションエンジンを示しています(したがって、アカウントのすべてのアクティブなセッションについてデータベースにクエリを実行するオプションを提供します)。
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.contrib.sessions.base_session import AbstractBaseSession
from django.db import models
class CustomSession(AbstractBaseSession):
account_id = models.IntegerField(null=True, db_index=True)
@classmethod
def get_session_store_class(cls):
return SessionStore
class SessionStore(DBStore):
@classmethod
def get_model_class(cls):
return CustomSession
def create_model_instance(self, data):
obj = super().create_model_instance(data)
try:
account_id = int(data.get('_auth_user_id'))
except (ValueError, TypeError):
account_id = None
obj.account_id = account_id
return obj
Djangoの組み込みcached_db
セッションストアからcached_db
に基づくカスタムセッションストアに移行する場合は、名前空間の衝突を防ぐために、キャッシュキープレフィックスをオーバーライドする必要があります。
class SessionStore(CachedDBStore):
cache_key_prefix = 'mysessions.custom_cached_db_backend'
# ...
URLのセッションID
Djangoセッションフレームワークは完全に、そして唯一、Cookieベースです。 PHPのように、最後の手段としてセッションIDをURLに入れることにフォールバックすることはありません。 これは意図的な設計上の決定です。 この動作はURLを醜くするだけでなく、「Referer」ヘッダーを介したセッションIDの盗難に対してサイトを脆弱にします。