如何解码Redis缓存中的Django会话值?
配置背景
为实现身份验证,采用Redis缓存存储Django会话,在settings.py中配置如下:
CACHES = { "default": { "BACKEND": "django.core.cache.backends.redis.RedisCache", "LOCATION": "redis://127.0.0.1:6379/0", } } SESSION_ENGINE = "django.contrib.sessions.backends.cache"
尝试读取所有会话时,运行了以下代码:
r = redis.StrictRedis('localhost', 6379, db=0, decode_responses=True) for key in r.keys(): print('Key:', key) print('Value:', r.get(key))
遇到的问题
- 当设置
decode_responses=False时,代码可正常运行,但返回结果为字节形式:
Key: b':1:django.contrib.sessions.cachec2ynyeuinke4i4815oi7bjjf3jzx100s' Value: b'\x80\x05\x95%\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x0f_session_expiry\x94K<\x8c\x07user_id\x94K\x01u.'
- 当设置
decode_responses=True时,触发Unicode解码错误:
Traceback (most recent call last):
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\django\views\decorators\csrf.py", line 56, in wrapper_view
return view_func(*args, **kwargs)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\django\views\generic\base.py", line 104, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\adrian\PyCharmProjects\TestProject\accounts\views.py", line 65, in post
print('Value:', r.get(key))
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\commands\core.py", line 1829, in get
return self.execute_command("GET", name)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\client.py", line 536, in execute_command
return conn.retry.call_with_retry(
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\retry.py", line 46, in call_with_retry
return do()
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\client.py", line 537, in
lambda: self._send_command_parse_response(
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\client.py", line 513, in _send_command_parse_response
return self.parse_response(conn, command_name, **options)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\client.py", line 553, in parse_response
response = connection.read_response()
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis\connection.py", line 500, in read_response
response = self._parser.read_response(disable_decoding=disable_decoding)
File "C:\Users\adrian\PyCharmProjects\TestProject\venv\lib\site-packages\redis_parsers\hiredis.py", line 128, in read_response
response = self._reader.gets()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
[28/Nov/2023 20:57:21] "POST /api/accounts/login/ HTTP/1.1" 500 129875
解决方案
Django会将会话数据以pickle序列化的形式存储在Redis中,因此需要用pickle反序列化字节数据来读取可读内容,代码如下:
r = redis.StrictRedis('localhost', 6379, db=0, decode_responses=False) for key in r.keys(): print('Key:', key) print(pickle.loads(r.get(key)))
内容的提问来源于stack exchange,提问作者Vlad Adrian

