将 Django SessionStore 使用的字符数从 32 扩展到 64
Extend number of characters used by Django SessionStore from 32 to 64
Django==1.11.17,Python==3.6.7
我想增加用于会话密钥的字符数。
正在寻找 django.contrib.sessions.backends.base.py
:
class SessionBase(object):
...
def _get_new_session_key(self):
"Returns session key that isn't being used."
while True:
session_key = get_random_string(32, VALID_KEY_CHARS)
if not self.exists(session_key):
break
return session_key
...
我要修改32 -> 64
.
我在我的一个文件中尝试了猴子补丁:
import django.contrib.sessions.backends.base as sessions_base
import django.contrib.sessions.backends.file as sessions_file
from django.utils.crypto import get_random_string
def _get_new_session_key(self):
while True:
session_key = get_random_string(64, sessions_base.VALID_KEY_CHARS)
print("SESSION KEY: {}".format(session_key))
if not sessions_file.SessionStore.exists(self, session_key):
break
return session_key
sessions_file.SessionStore._get_new_session_key = _get_new_session_key
django.contrib.sessions.backends.file.py
实现 SessionStore
和 exists()
.
这个解决方案只是被 Django 忽略了,我没有显示打印语句。
仅供参考,这确实打印了会话 ID(有 64 个字符)但出现错误:
sessions_file.SessionStore._get_new_session_key = _get_new_session_key(sessions_file.SessionStore)
File "/Users/.../lib/python3.6/site-packages/django/contrib/sessions/backends/file.py", line 51, in _key_to_file
session_key = self._get_or_create_session_key()
AttributeError: 'str' object has no attribute '_get_or_create_session_key'
问题:
这行不通。是不是因为SessionStore
对象在访问这个文件之前被中间件实例化了?
我的解决方案应该是一个中间件吗? (我宁愿猴子补丁)
注意:
也尝试过:
1. sessions_file.SessionStore.__dict__["_get_new_session_key"] = _get_new_session_key
<-- 出现错误
2. setattr(sessions_file.SessionStore, '_get_new_session_key', _get_new_session_key)` <-- 同样的问题,忽略
我使用以下代码成功覆盖了会话密钥长度:
import django.contrib.sessions.backends.base as sessions_base
from django.contrib.sessions.backends.db import SessionStore as OriginalSessionStore
from django.utils.crypto import get_random_string
def _get_new_session_key(self):
"Returns session key that isn't being used."
while True:
session_key = get_random_string(40, sessions_base.VALID_KEY_CHARS)
print("*********** SESSION KEY: {}, {}".format(len(session_key), session_key))
if not OriginalSessionStore.exists(self, session_key=session_key):
break
return session_key
OriginalSessionStore._get_new_session_key = _get_new_session_key
我在这个过程中确实发现,会话密钥长度有限制,40 个字符。
任何超过 40 个字符都会触发错误:
django.db.utils.DataError: value too long for type character varying(40)
我会继续寻找一种方法来修改会话密钥的类型以保存大于 40 个字符的值,因此欢迎任何指导。
谢谢!
编辑:
我在 Django.contrib.sessions.base_session.py
中找到了模型 AbstractBaseSession
:
@python_2_unicode_compatible
class AbstractBaseSession(models.Model):
session_key = models.CharField(_('session key'), max_length=40, primary_key=True)
目前正在评估覆盖它的影响、必要的迁移等
Django==1.11.17,Python==3.6.7
我想增加用于会话密钥的字符数。
正在寻找 django.contrib.sessions.backends.base.py
:
class SessionBase(object):
...
def _get_new_session_key(self):
"Returns session key that isn't being used."
while True:
session_key = get_random_string(32, VALID_KEY_CHARS)
if not self.exists(session_key):
break
return session_key
...
我要修改32 -> 64
.
我在我的一个文件中尝试了猴子补丁:
import django.contrib.sessions.backends.base as sessions_base
import django.contrib.sessions.backends.file as sessions_file
from django.utils.crypto import get_random_string
def _get_new_session_key(self):
while True:
session_key = get_random_string(64, sessions_base.VALID_KEY_CHARS)
print("SESSION KEY: {}".format(session_key))
if not sessions_file.SessionStore.exists(self, session_key):
break
return session_key
sessions_file.SessionStore._get_new_session_key = _get_new_session_key
django.contrib.sessions.backends.file.py
实现 SessionStore
和 exists()
.
这个解决方案只是被 Django 忽略了,我没有显示打印语句。
仅供参考,这确实打印了会话 ID(有 64 个字符)但出现错误:
sessions_file.SessionStore._get_new_session_key = _get_new_session_key(sessions_file.SessionStore)
File "/Users/.../lib/python3.6/site-packages/django/contrib/sessions/backends/file.py", line 51, in _key_to_file
session_key = self._get_or_create_session_key()
AttributeError: 'str' object has no attribute '_get_or_create_session_key'
问题:
这行不通。是不是因为
SessionStore
对象在访问这个文件之前被中间件实例化了?我的解决方案应该是一个中间件吗? (我宁愿猴子补丁)
注意:
也尝试过:
1. sessions_file.SessionStore.__dict__["_get_new_session_key"] = _get_new_session_key
<-- 出现错误
2. setattr(sessions_file.SessionStore, '_get_new_session_key', _get_new_session_key)` <-- 同样的问题,忽略
我使用以下代码成功覆盖了会话密钥长度:
import django.contrib.sessions.backends.base as sessions_base
from django.contrib.sessions.backends.db import SessionStore as OriginalSessionStore
from django.utils.crypto import get_random_string
def _get_new_session_key(self):
"Returns session key that isn't being used."
while True:
session_key = get_random_string(40, sessions_base.VALID_KEY_CHARS)
print("*********** SESSION KEY: {}, {}".format(len(session_key), session_key))
if not OriginalSessionStore.exists(self, session_key=session_key):
break
return session_key
OriginalSessionStore._get_new_session_key = _get_new_session_key
我在这个过程中确实发现,会话密钥长度有限制,40 个字符。
任何超过 40 个字符都会触发错误:
django.db.utils.DataError: value too long for type character varying(40)
我会继续寻找一种方法来修改会话密钥的类型以保存大于 40 个字符的值,因此欢迎任何指导。
谢谢!
编辑:
我在 Django.contrib.sessions.base_session.py
中找到了模型 AbstractBaseSession
:
@python_2_unicode_compatible
class AbstractBaseSession(models.Model):
session_key = models.CharField(_('session key'), max_length=40, primary_key=True)
目前正在评估覆盖它的影响、必要的迁移等