2016-06-27 72 views
0

我正在Rails中进行基于在线计算机的测试。每个问题都有一个形式为/questions/<id>的页面网址。
每个问题的页面上都有一个“下一个”按钮,指向下一个问题,如/questions/<another-id>。我不希望用户手动输入任何问题的网址并转到该页面。
有什么办法可以实现这一点,最好是服务器端解决方案。如何限制对rails中页面的访问,除非用户通过特定页面的链接来访问?

+0

作为一个简单的(但不是非常安全的)解决方案,你可能有“下一步”按钮来提交表单(也许是空的),并且只允许/ questions/id路径在POST中可用而不是GET?这种方式输入URL将不会工作,因为它会导致GET请求。 –

回答

2

我对你有一个服务器端解决方案可能是将解决你的问题如下说明如下......

  1. 假设,你有一个固定的链接,用户可以开始测试。

  2. 一旦用户开始测试,然后添加问题-ID到会话像下面...

    会话[:电流问题-ID] =参数[:question_id]

  3. 总是检查下一个问题ID增加一个sesssion问题ID,如果匹配,然后显示问题或不做任何重定向回。

该解决方案将工作,如果你有问题的序列,如1,2,3 ... n。

4

您可以使用:

Friendly ID Gem,这将你的ID转换成团状,从而使最终用户无法确定究竟是传递到URL参数。

1

有点像巴拉特瑞里:

就可以构建结合你的问题Id和连接到用户会话的随机数建立了一个ID的URL。

您可以使用SHA1(或您选择的算法)组合这两个值。例如:

问题编号:123

秘密会话哈希:857c9e05-8ad0-4d6b-8112-5f442a731dc1(SecureRandom.uuid上的会话#创建)

计算您摘要:

Digest::SHA1.hexdigest "#{question_id}#{secret_session_hash}"

=> e951774237433335a6c9c0928d5691ca0c2a31b5

建立您的网址:

website/question/123?key=e951774237433335a6c9c0928d5691ca0c2a31b5

你必须确保你的控制器摘要你PARAMS收到[:键]就是消化你计算相同。

通过这种方式,您可以合理地确保您的用户不会作弊,并且他无法将网址提供给其他人。