【发布时间】:2015-09-28 16:22:15
【问题描述】:
我有一个基于数据库的会话存储解决方案。效果很好!但是,我在存储特定类型的数据时遇到了问题。
我有一个使用 CSRF 令牌的应用程序。创建表单时,它将为该表单创建一个令牌。令牌是不同类型值的散列 (sha256) 值。一份副本进入表单,另一份副本存储在会话中。提交表单后,它会比较令牌以确保它们匹配。
以下是使用新数据更新数据库的 destruct 函数示例
UPDATE session_manager SET variables= :variables WHERE 1=1 AND id = :id
array(2) {
[":variables"]=>
string(152) "a:1:{s:4:"CSRF";a:1:{s:8:"register";a:2:{s:5:"token";s:64:"e749603241dec1911ef3a40d98b2f5185d389434060483297394b504cc904ede";s:4:"time";i:1443456816;}}}"
[":id"]=>
string(2) "49"
}
更新语句很好并且工作正常。这是我遇到的问题,数据已更新,但是您可以在上面的数据中看到的“令牌”值与下面的 db 中的值不同(这是数据的二进制下载):
a:1:{s:4:"CSRF";a:1:{s:8:"register";a:2:{s:5:"token";s:64:"b48fc79fc2f51eff765c05476895238a42d9d45b2c1aeb7c6e4582d0381b7f4f";s:4:"time";i:1443456817;}}}
似乎 mysql 正在改变值,我终其一生都无法弄清楚这个问题。我尝试过的解决方案包括:
- 序列化
- json_encode
- base64
更改数据库的字符集等等。在数据库中尝试了不同的字段类型,例如 TEXT、Longtext 和 BLOB。这似乎对我不起作用:(
这是 db 的 sql
CREATE TABLE session_manager(
id BIGINT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL,
session_id VARCHAR(200),
user_agent TINYTEXT NOT NULL,
variables BLOB NOT NULL,
initial_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
regenerate_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);
你想到了什么原因?
【问题讨论】:
-
我不认为 MySQL 正在改变你的价值。您必须在 php 代码中为更新提供不同的字符串...您正在使用准备好的语句进行更新...在更新语句之前尝试
echo $tokenValue;以验证值 -
您在更新语句之后看到的数组是执行 db 查询之前绑定参数的转储。
-
使用
Text作为类型,它可能无法解决问题,但这是解决问题的建议之一。我面对它。 -
另外,以下代码取自我的一个工作项目
$this->attributes['options'] = base64_encode(serialize($options));供阅读return unserialize(base64_decode($options));。 -
我会试一试的。就像一个有趣的问题一样,添加 base64 不会增加服务器的负载吗?还是可以忽略不计?