2

ファイルベースのセッションエンジンを使用しても、セッションが期限切れにならないことに気づきました。ファイルベースのセッションのDjangoコードを見ると、Djangoはセッションの有効期限情報を保存しないため、セッションファイルを手動で削除しない限り、有効期限が切れることはありません。

これは私にはバグのように見えます。データベースでバックアップされたセッションは正常に機能し、どのセッションのバックエンド開発者が選択したかに関係なく、すべて同じように動作するはずです。

ユーザーのセッションをファイルに保存する必要があるため、データベースに基づくセッションに切り替えることはできません。

誰かがいくつかの光を当てることができますか?これは本当にバグですか?はいの場合、どのように私にそれを回避するように提案しますか?

ありがとう!

4

3 に答える 3

3

ですから、あなたが正しいように見えます。少なくともdjango1.4では、を使用するdjango.contrib.sessions.backends.fileと完全に無視されSESSION_COOKIE_AGEます。それが本当にバグなのか、それとも文書化されていないだけなのかはわかりません。

この機能が本当に必要な場合は、contribのファイルバックエンドに基づいて独自のセッションエンジンを作成できますが、有効期限機能を使用して拡張できます。

django/contrib/sessions/backends/file.py次のインポートを開いて追加します。

import datetime
from django.utils import timezone

次に、loadメソッドに2行を追加して、次のように表示します。

def load(self):
    session_data = {}
    try:
        session_file = open(self._key_to_file(), "rb")
        if (timezone.now() - datetime.datetime.fromtimestamp(os.path.getmtime(self._key_to_file()))).total_seconds() > settings.SESSION_COOKIE_AGE:
            raise IOError
        try:
            file_data = session_file.read()
            # Don't fail if there is no data in the session file.
            ....

これにより、実際にはセッションファイルの最終変更日が比較されて期限切れになります。

このファイルをプロジェクトのどこかに保存し、SESSION_ENGINE代わりにとして使用します'django.contrib.sessions.backends.file'

SESSION_SAVE_EVERY_REQUEST非アクティブに基づいてセッションをタイムアウトする場合は、設定で有効にする必要もあります。

于 2012-04-17T20:44:35.387 に答える
0

オプションはtmpwatch、セッションを保存するディレクトリで使用することです

于 2012-04-17T20:58:14.263 に答える
0

で同様の問題が発生しましたDjango 3.1。私の場合、私のプログラムは、セッションの有効期限をチェックする前にset_expiry(value)、整数引数(データ型)を使用して関数を呼び出します。int

Djangoのドキュメントによると、引数valueのデータ型はset_expiry()、、またはです。ただし、ファイルベースのセッションの場合、引数が事前に渡された場合にのみ内部の有効期限チェックが正しく機能せず、このような問題は発生しません。intdatetimetimedeltaload()intset_expiry()datetimetimedeltaset_expiry()

簡単な解決策(回避策?)は、へのint引数を回避することです。set_expiry(value)サブクラス化django.contrib.sessions.backends.file.SessionStoreしてオーバーライドすることでこれを行うことができset_expiry(value)(以下のコードサンプル)、SESSION_ENGINEそれに応じてパラメーターを変更します。settings.py

from datetime import timedelta
from django.contrib.sessions.backends.file import SessionStore as FileSessionStore

class SessionStore(FileSessionStore):
    def set_expiry(self, value):
        """ force to convert to timedelta format """
        if value and isinstance(value, int):
            value = timedelta(seconds=value)
        super().set_expiry(value=value)

:渡すtimedeltaまたは渡すdatetimeこともできますが、オブジェクトのシリアル化の問題set_expiry(value)を処理する必要があります。datetime

于 2020-10-29T04:40:41.743 に答える