Python取消序列化PHP会话

uxhixvfz  于 2022-12-28  发布在  Python
关注(0)|答案(3)|浏览(94)

我一直在尝试使用phpserialize和一个serek的模块(从Unserialize PHP data in python获得)在Python中反序列化PHP会话数据,但这对我来说似乎是不可能的。
两个模块都期望PHP会话数据如下所示:

a:2:{s:3:"Usr";s:5:"AxL11";s:2:"Id";s:1:"2";}

但会话文件中存储的数据是:

Id|s:1:"2";Usr|s:5:"AxL11";

任何帮助都将不胜感激。

xyhw6mcr

xyhw6mcr1#

在Google上到达第3页后,我找到了原始应用程序phpserialize的一个fork,它与我提供的字符串一起工作:

>>> loads('Id|s:1:"2";Usr|s:5:"AxL11";')
{'Id': '2', 'Usr': 'AxL11'}
bbuxkriu

bbuxkriu2#

PHP session 序列化使用的默认算法 * 不是 * serialize使用的算法,而是另一种内部损坏格式php,它
无法存储数字索引,字符串索引也无法在$_SESSION.中包含特殊字符(|!
正确的解决方案是将残缺的默认会话序列化格式更改为Armin Ronacher的原始phpserialize库支持的格式,或者甚至通过更改session.serialize_handler INI设置将其序列化和反序列化为JSON。
我决定使用前者来实现PHP端的最大兼容性,方法是使用

ini_set('session.serialize_handler', 'php_serialize')

这使得新会话与标准phpserialize兼容。

41zrol4v

41zrol4v3#

我就是这么做的,很蠢:
首先,将Id|s:1:"2";Usr|s:5:"AxL11";转换为查询字符串Id=2&Usr=AxL11&,然后使用parse_qs

import sys
import re

if sys.version_info >= (3, 0):
    from urllib.parse import parse_qs, quote
else:
    from urlparse import parse_qs
    from urllib import quote

def repl(m):
    return '=' + quote(m.group(2)[:int(m.group(1))]) + '&'

def parse_php_session(path):
    with open(path, 'r') as sess:
        for name, value in parse_qs(
                    re.sub('\|s:([0-9]+):"(.*?)";(?=[^\|]+\|s:[0-9]+:"|$)', repl, sess.read().rstrip(';') + ';')
                ).items():
            yield name, value[-1]

for name, value in parse_php_session('/session-save-path/sess_0123456789abcdef'):
    print('%s: %s' % (name, value))

它过去工作时不需要将;替换为&(两者都允许),但是从Python 3.10开始,parse_qs的默认分隔符是&

相关问题