Javascript 如何检查AJAX请求的真实性
我正在设计一个网站,让用户尽可能快地解决谜题。JavaScript用于为每个拼图计时,当拼图完成时,毫秒数通过AJAX发送到服务器。如何确保服务器收到的时间不是由用户伪造的 我认为基于会话的真实性令牌(Rails中表单使用的那种令牌)不够,因为我需要验证值的来源,而不仅仅是验证请求的合法性 有没有办法对请求进行加密签名?我想不出任何黑客不能复制的东西。任何JavaScript,就其暴露的客户端性质而言,都会受到篡改吗?我是否必须使用一些编译过的东西,比如Flash?(伊克斯)或者有什么办法可以隐藏一把秘密钥匙?或者其他我没想到的事Javascript 如何检查AJAX请求的真实性,javascript,ajax,security,language-agnostic,encryption,Javascript,Ajax,Security,Language Agnostic,Encryption,我正在设计一个网站,让用户尽可能快地解决谜题。JavaScript用于为每个拼图计时,当拼图完成时,毫秒数通过AJAX发送到服务器。如何确保服务器收到的时间不是由用户伪造的 我认为基于会话的真实性令牌(Rails中表单使用的那种令牌)不够,因为我需要验证值的来源,而不仅仅是验证请求的合法性 有没有办法对请求进行加密签名?我想不出任何黑客不能复制的东西。任何JavaScript,就其暴露的客户端性质而言,都会受到篡改吗?我是否必须使用一些编译过的东西,比如Flash?(伊克斯)或者有什么办法可以隐
更新:澄清一下,我不想惩罚网络连接速度慢的人(网络速度应该被认为是不一致的),因此计时需要100%客户端(只有当我们知道用户可以看到谜题时计时器才会启动)。而且,这涉及到钱,所以“信任用户”是不可接受的。对不起,为什么你不能在服务器上使用时间?您收到响应的时间将是用于计算分数的时间。根据服务器端实现,您可以将计时功能放在服务器端。记录网页请求发出的时间(如果愿意,您可以将其放入数据库),然后在收到答案时获取当前时间,并执行一些算法以获取答案的持续时间。如果您愿意,您可以将时间存储在会话对象中,而不是数据库中,尽管我对其中的完整性不太了解。您无法以加密方式保证计时的安全性,因为客户端的浏览器无法进行安全计算。通过调整实际计时,可以绕过任何与服务器进行加密的方法 服务器上的定时也不起作用——如果不考虑往返时间中的延迟,具有较低延迟连接的用户将具有优势;如果您这样做,用户可以通过在补偿阶段添加额外的延迟,然后在以后删除它来阻止补偿阶段 当然,您可以让用户很难修改它,但是模糊安全性无论如何都是不可持续的策略 因此,归根结底,要么在某种程度上信任你的用户(大多数情况下,这是一个合理的假设),要么设计游戏,使其不至于忽略时间安排。你必须在这里使用服务器端时间。我会这样做: 对服务器执行ping操作。当服务器端代码接收到ping时,将服务器端时间存储为会话变量(确保该变量不存在)。当他们完成测验时,再次记录服务器端时间,并将其与会话变量进行比较,以确定他们的持续时间。删除会话变量 为什么会这样:
- 在他们看到测验之前,你不能启动计时器
- 网络延迟被考虑在内,因为计时器在AJAX请求到来之前不会启动(如果他们的连接速度慢,AJAX请求就会慢)
- Ping不是伪造的,因为您在存储之前确保会话变量不存在
编辑:我想补充一点,您可以继续保留客户端时间,并将其包含在最后一篇文章中。然后可以将其与服务器端计算的时间进行比较。如果它们相当接近,那么您可以信任客户端时间。我这样做的方式是,当服务器向客户端发送谜题时,当前时间存储在会话中。这样可以确保在发送拼图后立即开始计时。完成拼图并发送到服务器以检查拼图是否正确完成后,服务器再次检查时间并进行比较
很明显,缓慢的互联网连接会使这段时间变长,但你对此无能为力。在客户端启动和停止计时器时不可能不担心被操纵 您在客户端执行的任何操作都可以更改/停止/绕过 在客户端进行加密/解密也是不安全的,因为他们可以在加密之前更改信息 因为涉及金钱,用户是不可信的 定时必须在服务器上启动,并且必须在服务器上停止 如果拼图内容返回ajax调用结果,则仅使用ajax在服务器上启动计时器。不要加载拼图,然后发送一个ajax请求,因为在他们查看拼图时,这可能会被劫持和延迟
.正如其他一些人指出的那样:
PUZZLE_RECEIVED
TOKEN_RECEIVED
PUZZLE_COMPLETED
PUZZLE_SENT
TOKEN_SENT
PUZZLE_COMPLETED.time - PUZZLE_RECEIVED.time
PUZZLE_RECEIVED.time - PUZZLE_SENT.time
TOKEN_RECEIVED.time - TOKEN_SENT.time