【问题标题】:voting - stopping abuse from client side - ASP.NET MVC投票 - 从客户端停止滥用 - ASP.NET MVC
【发布时间】:2010-02-14 07:15:27
【问题描述】:
所以我设计了这个投票工具,它不会让某人在 24 小时内为同一篇文章投票两次。但是,假设一个人投票,并且在看到该人能够投票或者他正在那个 24 小时窗口内,我禁用了投票按钮(这都是 Ajax 顺便说一句)。
但是当一个人关闭他/她的浏览器并返回甚至刷新页面时该怎么办?显然,由于我的算法,他将无法投票,但该人最终仍会成功调用服务器。所以如果他真的想要,他会不断刷新页面并点击投票,给服务器带来不必要的负载。如何通过做某种客户端的事情来避免这种情况?
我使用的是 ASP.NET MVC,所以会话变量是没有问题的。
我是否对此过于担心?
【问题讨论】:
标签:
asp.net-mvc
client-side
【解决方案1】:
如果投票只发生在已登录的(已知)成员中,那么您应该没有任何问题。
另一方面,如果每个人都可以投票,那么您需要存储所有用户投票事件:
- 时间戳
- 民意调查
- poll_vote
- ip
- 用户代理
- 用户唯一性 cookie
因此,您需要一个随机散列作为 cookie 发送出去。这将确保您不会接受同一个人对同一投票的另一票。
如果用户删除了他的 cookie,您将退回到计划 B,在该计划中,您在 24 小时内不允许来自同一 IP 和用户代理组合的投票超过(例如)10 票。
该系统并不完美,因为用户可以更改 IP 和(更容易)用户代理。您需要先进的模式检测算法来检测可疑投票。存储所有用户投票事件的好处是您可以稍后使用调度程序处理这些事件,或者将投票外包给可以为您处理它们的其他人。
祝你好运
【解决方案2】:
刷新不是问题
- 如果您使用 Ajax 进行所有这些投票,那么除了使用 GET 加载页面之外,刷新页面不会做任何事情。
- 如果您不使用 Ajax,则应确保调用 RedirectToAction/RedirectToRoute 操作结果,这也有助于避免刷新问题。
你如何识别用户
如果您使用某种用户身份验证,则重新投票不会有问题。但是,如果您的用户是纯匿名的,您应该在投票中存储 IP 地址。事情通常是这样完成的。这也可以避免会话变量。但是您必须了解这种技术,因为它不是 100% 完美的。
Cookie?
您当然也可以使用绝对过期 cookie。他们将在一天内到期。高级用户当然可以避免您的投票限制,但他们也可以避免其他方式。顺便说一句,会话也基于 cookie。
组合
但是当你想让你的系统尽可能好时,你可能会使用以上的组合。
【解决方案3】:
最好的方法是在服务器上跟踪谁在什么时间和什么时间投票(可能将其存储在数据库中)。为此,您必须在您的站点上使用身份验证系统(可能是forms authentication)来识别用户。因此,每当有人尝试投票时,您首先检查您的数据存储是否他已经投票,以及何时并决定是否验证投票。这是最可靠的方法。
如果您的站点是匿名的(投票时不需要身份验证),那么您可以在客户端计算机上存储一个持续 24 小时的持久性 cookie,并表明已经从这台计算机上进行了投票。请记住,cookie 可能会被禁用、删除,并且不是识别给定用户的可靠方法。
我正在使用 ASP.NET MVC,所以会话
变量是没有问题的。
有什么理由吗?会话在 ASP.NET MVC 应用程序中非常好。在您的情况下,它们将不起作用,因为如果用户关闭浏览器,他将失去会话。
显然,他不能
投票,因为我的算法,
但这个人最终还是会
成功调用
服务器。所以如果他真的想要,他
会不断刷新页面和
点击投票并放
服务器上不必要的负载
自动化机器人还可能给您的服务器带来不必要的负载,这比单个用户点击 F5 重要得多。
【解决方案4】:
如果您只是想确保用户只能对一篇文章投票一次,那么您只需存储他们已经投票过的所有文章 ID 的 Set(即 HashSet),然后在允许投票之前进行检查。
如果您仍然想要 24 小时限制,那么您需要存储一个 Dictionary<articleId,DateTime>,然后您可以检查他是否已经为该文章投票,以及他在何时投票。