我正在建立一个调查页面,其中用户有一个有限的时间来回答他们的所有问题。给定的时间以@test.time_allowed的形式存储在模型中,它是一个表示秒的整数。
我需要一种简单且不可被用户篡改的方法来让计时器显示在视图上,并在计时器转到0时执行控制器操作。我如何才能做到这一点呢?
我是一个相对的初学者,所以任何具体的答案都会很有帮助。谢谢。
-更新
@Bryan:
我假设有一种防篡改的方法,如果时间是在服务器端完成的?例如,您建议的客户端上可能有一个javascript计时器,但是提交时,提交时间不能与窗口初始加载的时间进行比较吗?
发布于 2010-07-22 01:45:35
由于从客户端返回的数据永远不能完全信任,因此服务器必须以某种方式知道最初生成的表单的时间戳是什么。这可以通过在会话或数据库中保存变量来完成,但这是有问题的。相反,服务器可以在表单中放置一个时间戳,加密的或签名的,以确保客户端没有更改它。然后,服务器可以根据需要拒绝提交。在客户端,单独的逻辑可以处理UI部分,向用户提供有关时间限制的反馈,但最终这只是松散地耦合到服务器处理。
详细信息:
服务器应该生成两个表单字段:一个具有系统时间戳time = Time.now.to_i以跟踪表单生成的时间,另一个具有签名Digest::MD5.hexdigest(time.to_s.concat('Some-secret-string-1234')) (请注意,此处对时间戳表单域和签名表单域使用相同的时间值)。这将验证提交的表单是否带有服务器生成的时间戳,该时间戳未被客户端更改。
您也可以发送另一个具有时间限制的表单域。
在客户端,读取时间戳,使用setTimeout和时间限制来生成倒计时或任何您想在前端执行的操作。
提交表单时,通过使用与前面相同的方法重新生成MD5签名来验证与表单一起提交的时间戳。确保它与表单提交的签名相匹配。然后,将时间戳添加到超时,并确保它晚于当前服务器时间。如果是这样的话,你有一个有效的提交,在你的时间限制。
您可能需要在服务器端的超时上给出比在客户端上更多的回旋余地,也许是几秒钟,以说明网络延迟,否则用户可能会看到还剩一秒,单击submit,然后在收到服务器请求时,计时器似乎已经超时。
确保添加require 'digest/md5'才能访问MD5。
使用这样的MD5签名是验证客户端没有以无状态的方式更改表单中的关键参数的一种很好的方法。这对你的小把戏来说是一个很好的补充。
祝好运!
发布于 2010-07-21 14:08:48
没有100%防篡改的方法来实现这一点,因为你需要使用JavaScript来实现这一点,它可以被足够恶意的用户关闭或操纵。
但是,如果您不关心这些问题,您可以简单地在页面上设置一个超时时间,以便在秒数过后提交表单。要做到这一点,您需要类似于下面的内容。显然,timeInMilliseconds需要从服务器端的模板生成到页面中。
window.setTimeout(function() {
document.forms['survey_form'].submit();
},
timeInMilliseconds);发布于 2010-07-22 01:45:41
为正在进行的调查创建模型,并添加将deadline设置为Time.now + survey_duration的after_create过滤器。在模型中保留拒绝延迟发送答案的逻辑。
https://stackoverflow.com/questions/3296628
复制相似问题