Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何检查AJAX请求的真实性_Javascript_Ajax_Security_Language Agnostic_Encryption - Fatal编程技术网

Javascript 如何检查AJAX请求的真实性

Javascript 如何检查AJAX请求的真实性,javascript,ajax,security,language-agnostic,encryption,Javascript,Ajax,Security,Language Agnostic,Encryption,我正在设计一个网站,让用户尽可能快地解决谜题。JavaScript用于为每个拼图计时,当拼图完成时,毫秒数通过AJAX发送到服务器。如何确保服务器收到的时间不是由用户伪造的 我认为基于会话的真实性令牌(Rails中表单使用的那种令牌)不够,因为我需要验证值的来源,而不仅仅是验证请求的合法性 有没有办法对请求进行加密签名?我想不出任何黑客不能复制的东西。任何JavaScript,就其暴露的客户端性质而言,都会受到篡改吗?我是否必须使用一些编译过的东西,比如Flash?(伊克斯)或者有什么办法可以隐

我正在设计一个网站,让用户尽可能快地解决谜题。JavaScript用于为每个拼图计时,当拼图完成时,毫秒数通过AJAX发送到服务器。如何确保服务器收到的时间不是由用户伪造的

我认为基于会话的真实性令牌(Rails中表单使用的那种令牌)不够,因为我需要验证值的来源,而不仅仅是验证请求的合法性

有没有办法对请求进行加密签名?我想不出任何黑客不能复制的东西。任何JavaScript,就其暴露的客户端性质而言,都会受到篡改吗?我是否必须使用一些编译过的东西,比如Flash?(伊克斯)或者有什么办法可以隐藏一把秘密钥匙?或者其他我没想到的事


更新:澄清一下,我不想惩罚网络连接速度慢的人(网络速度应该被认为是不一致的),因此计时需要100%客户端(只有当我们知道用户可以看到谜题时计时器才会启动)。而且,这涉及到钱,所以“信任用户”是不可接受的。

对不起,为什么你不能在服务器上使用时间?您收到响应的时间将是用于计算分数的时间。

根据服务器端实现,您可以将计时功能放在服务器端。记录网页请求发出的时间(如果愿意,您可以将其放入数据库),然后在收到答案时获取当前时间,并执行一些算法以获取答案的持续时间。如果您愿意,您可以将时间存储在会话对象中,而不是数据库中,尽管我对其中的完整性不太了解。

您无法以加密方式保证计时的安全性,因为客户端的浏览器无法进行安全计算。通过调整实际计时,可以绕过任何与服务器进行加密的方法

服务器上的定时也不起作用——如果不考虑往返时间中的延迟,具有较低延迟连接的用户将具有优势;如果您这样做,用户可以通过在补偿阶段添加额外的延迟,然后在以后删除它来阻止补偿阶段

当然,您可以让用户很难修改它,但是模糊安全性无论如何都是不可持续的策略

因此,归根结底,要么在某种程度上信任你的用户(大多数情况下,这是一个合理的假设),要么设计游戏,使其不至于忽略时间安排。

你必须在这里使用服务器端时间。我会这样做:

对服务器执行ping操作。当服务器端代码接收到ping时,将服务器端时间存储为会话变量(确保该变量不存在)。当他们完成测验时,再次记录服务器端时间,并将其与会话变量进行比较,以确定他们的持续时间。删除会话变量

为什么会这样:

  • 在他们看到测验之前,你不能启动计时器
  • 网络延迟被考虑在内,因为计时器在AJAX请求到来之前不会启动(如果他们的连接速度慢,AJAX请求就会慢)
  • Ping不是伪造的,因为您在存储之前确保会话变量不存在

编辑:我想补充一点,您可以继续保留客户端时间,并将其包含在最后一篇文章中。然后可以将其与服务器端计算的时间进行比较。如果它们相当接近,那么您可以信任客户端时间。

我这样做的方式是,当服务器向客户端发送谜题时,当前时间存储在会话中。这样可以确保在发送拼图后立即开始计时。完成拼图并发送到服务器以检查拼图是否正确完成后,服务器再次检查时间并进行比较


很明显,缓慢的互联网连接会使这段时间变长,但你对此无能为力。

在客户端启动和停止计时器时不可能不担心被操纵

您在客户端执行的任何操作都可以更改/停止/绕过

在客户端进行加密/解密也是不安全的,因为他们可以在加密之前更改信息

因为涉及金钱,用户是不可信的

定时必须在服务器上启动,并且必须在服务器上停止

如果拼图内容返回ajax调用结果,则仅使用ajax在服务器上启动计时器。不要加载拼图,然后发送一个ajax请求,因为在他们查看拼图时,这可能会被劫持和延迟


.

正如其他一些人指出的那样:

  • 您必须使用服务器时间,因为客户端时间容易被操纵
  • 检查服务器上的时间可能会惩罚网络连接速度慢的人或距离远的人
  • 这个问题的答案是在客户端和服务器之间使用一个时间同步协议,类似于NTP使用的协议。客户端和服务器协同工作,确定由网络延迟引起的延迟量。然后将此因素考虑到给每个用户的时间中

    NTP的算法非常复杂,经过多年的发展。但下面是一个简单的方法;我认为该协议应该有效,但您可能希望对其进行测试

    让客户端通过两次连续的HTTP XMLRPC ping来测量往返时间。每个ping返回不同的nonce。第二次ping需要来自第一次ping的nonce,以确保它们是连续的。当从cli发送第二个HTTP ping时,谜题时间开始
    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