我有一个表单,其中有一个“令牌”字段,每个页面都是唯一的:
<form ...>
...
<input type="hidden" name="token" value="325324" />
</form>
每次生成此唯一令牌都会存储在数据库中。
当表单被提交时,处理该处理的控制器将检查数据库,以查看提交的令牌字段值是否存在于数据库中并完成它的工作。
完成这些操作后,控制器会重定向到同一页面,但会向网址?updated=1"
添加查询参数。
如果存在“更新的”查询参数,页面将显示一条消息,通知提交表单的用户,他的更改已更新。
所以一切都很好,除非我用?updated=1"
参数刷新页面,我会看到相同的消息,这并不真实地反映现实,因为表单未提交:)
我知道这不重要,因为它不是安全问题,但我仍然想要解决它。我通过创建另一个令牌找到了一个解决方案,让我们将它称为token2,当我重定向为查询参数时,我将其传递给URL。然后,当页面检查该updated
参数时,它还将检查数据库中是否存在token2。如果是,它将删除它,然后显示消息。因此,URL中具有相同token2参数的任何其他请求都不会触发该消息。
但我不喜欢在每个页面的数据库中存储两个令牌的想法。我可以以某种方式使用第一个令牌来检测我是否应该显示该消息吗?
不确定是否重要,但这些一次性令牌在一小时后过期,所有过期的令牌每天会自动从数据库中删除两次。
答案 0 :(得分:1)
考虑向此表(DB)添加另一个字段,名为“已提交”。
1.User到达表单(生成令牌)
2.插入(token , submitted) values ('blabla' , '0')
3.用户提交表格
4.处理处理的控制器将检查数据库以查看是否存在 提交的令牌字段值存在于数据库中 将submitted
的值更新为1
。
5.控制器还用?update = 1重新加载页面,然后你就会有一个条件:
if submitted == 1 : update submitted = 0
因此,如果用户现在重新加载页面(通知现在提交= 0),您将显示表单而不是消息。
答案 1 :(得分:1)
使用数据库获取这些令牌很好,但我认为你可能会更好地使用这种数据的会话,特别是因为它是瞬态的。它也可以简化你的代码。
至于你的具体问题,人们似乎忘记了在发出视图后你实际上可以执行代码。你的逻辑是这样的:
if ($_SESSION['updated']) {
$view->addUpdatedMessage();
}
$_SESSION['updated'] = false;