我正在使用 Edit in Place jquery插件,该插件需要将数据发布到将执行实际数据库更新的脚本。
此更新脚本的URL可以在html源代码和Firebug中轻松查看,因此我需要在处理更新之前添加某种身份验证检查。这当然是因此用户不能只传入他们想要的任何旧的用户ID /字段/值并且弄乱其他人的记录。
我最初也传递了他们的用户名和密码,但这并不理想,因为它在GET请求中,所以它都在URL中。该网站本身至少是SSL,但在任何情况下都不是最佳做法。
验证此类更新的最佳方法是什么?
FWIW,更新脚本是PHP格式,“就地编辑”插件是:jeditable。
编辑:澄清一下:实际的数据有效负载是POST给脚本的,但是就地编辑插件没有明确的身份验证方法,因此我将身份验证作为URL的一部分传递给更新脚本,然后通过GET获取这些变量并使用它们进行检查。
编辑2:是的,我可以从更新脚本访问会话信息,所以我决定只提取以前保存的用户ID并在db update语句中使用它。这似乎是最安全的方法。
答案 0 :(得分:3)
我认为你最好将脚本切换到POST方法,因为大多数编辑就地使用太大而无法实际使用GET。您永远不应该使用SessionId或密码作为URL参数,除了查看公共配置文件之外,我不会使用用户名。如果你的AJAX URL是一个PHP文件,我很确定它应该能够访问会话而无需在GET或POST数组中传递它。另外,请确保在更新数据库之前验证并清理所有信息。
答案 1 :(得分:2)
更新(根据评论和问题更新):您可以将用户名/密码作为submitdata
选项传递给Jeditable,如下所示:
$(".edit_area")
.editable("http://www.example.com/save.php", {
submitdata: { userid:'johnsmith', passwd:'god' }
// ..other settings, etc.
});
快速和脏解决方案 - 脏,因为它以明文(通过查看源)公开用户的私有。
由于你做可以访问服务器上的userid / sessionid,所以使用到目前为止的sanest选项。
嗯...既然你说Jeditable使用GET,我只能假设你使用的是 loadurl
选项(因为Jeditable使用$.post()
来保存更改,并且{{ 1}} 总是使用POST)。
那么,您是否尝试将Jeditable的$.post()
设置切换为“POST”,并像以前一样发送用户名/密码?
loadtype
这听起来像是快速而肮脏的解决方案 - 授予您在服务器端没有任何标准用户/会话处理。
答案 2 :(得分:2)
如果您只是在会话中查找用户,该网站是否仍然容易受到跨网站请求伪造的攻击?
如果您包含根据不可编辑POST字段的值计算的盐渍哈希字段,则可以发布所有需要的信息。如果包含时间戳,则也可以阻止脚本重放。
示例:
$(".edit_area")
.editable("http://www.example.com/save.php", {
submitdata: {
userid: 'johnsmith',
pageid: '123', // or other value unique to the page
timestamp: '1324354657', // time when page loaded
hash: '0bee89b07a248e27c83fc3d5951213c1' }
// ..other settings, etc.
});
散列可以是例如MD5为'johnsmith$123$1324354657$' + $secret_salt
。保存之前检查它是否匹配。如果时间太少或太多,可以选择拒绝。
ditch-pycrypto branch of django-magicforms将此实现为Django的可重用Form基类。它不直接适用于AJAX请求,但文档和单元测试应该为其他实现提供良好的基础。
答案 3 :(得分:-2)
要传递信息,您应该在实际的GET字符串中使用会话ID。这样,php脚本可以连接到会话,验证用户,并查看用户是否有权编辑他们发布的内容。然后,如果他们拥有权限,请继续,否则返回错误消息。
我相信你可以在javascript中获取会话ID,因此不需要公开传递。