Django SessionStore使用的字符数从32扩展到64

时间:2018-12-16 21:03:54

标签: django monkeypatching django-sessions

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实现SessionStoreexists()
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'

问题:

  1. 这不起作用。是由于SessionStore对象由于访问此文件之前由于中间件而实例化的事实?

  2. 我的解决方案应该是中间件吗? (我宁愿是猴子补丁)

注意:

也尝试过:
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)`<-相同的问题,被忽略

1 个答案:

答案 0 :(得分:0)

我设法使用以下代码成功覆盖了会话密钥长度:

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个字符的值,因此欢迎您提供任何指导。

谢谢!

编辑:

我在AbstractBaseSession中找到了模型Django.contrib.sessions.base_session.py

@python_2_unicode_compatible
class AbstractBaseSession(models.Model):
    session_key = models.CharField(_('session key'), max_length=40, primary_key=True)

当前正在评估对其进行覆盖,必要的迁移等的含义。