0

我正在我的 MVC 项目中开发一个投票机制应用程序,我要求用户在浏览器中只允许投票一次,如果他在同一个浏览器中第二次到达投票页面,他不应该能够投票但如果他在另一个浏览器中登录,他应该能够再次投票。

为此,我使用了 Cookie 来处理这种情况。我所做的是将 UserID 添加到 cookie 中,并在查看页面中检查投票按钮是否可见。

我的看法是

@if ((ViewData["CookieData"] == null) || (ViewData["CookieData"].ToString() != Session["LoginPersonID"].ToString()))
{    
        <button name="button" value="Insert" onclick="return confirm('Are you sure you want to submit your choices ?.');">Vote Now!!</button>
        <br />  
        @Html.ActionLink("Back to Home Page", "EmployeeHomePage", "Employee", new { logedinperson = Session["LoginPersonID"] }, null);
}

我的控制器是

public void AddCookie()
{            
    HttpCookie MyCookie = new HttpCookie("MyCookie", Session["LoginPersonID"].ToString());           
    MyCookie.Expires = DateTime.Now.AddDays(30);           
    Response.Cookies.Add(MyCookie);
    ViewData["CookieData"] = MyCookieCollection;       
}

当第一个用户说 PersonA 在 Firefox 中登录并投票时,他的 personid 存储在 cookie 中,因此如果他再次尝试访问投票页面,投票按钮将不可见,但随后他尝试在 Google Chrome 上打开他可以投票。那也按预期工作。现在当 PersonB 在 Firefox 中登录并投票时,他的 personid 会在 cookie 中更新,因此他也无法在同一浏览器中第二次投票。

但我的确切问题是当 PersonA 再次登录到 Firefox 时,他能够投票,因为 cookie 已使用 PersonB 的 id 进行了更新。那么无论如何,如果 PersonA 和 PersonB 已经在浏览器中投票,我该如何限制他们。

4

3 回答 3

1

我看到的一个问题是您从未从请求中读取 cookie。您的控制器始终在创建 cookie 并将其与响应一起发回。相反,您应该首先检查是否存在 cookie,然后采取相应措施。

另一个方面是,如果您希望每个帐户的 cookie,您需要为每个帐户创建不同的 cookie(即根据用户 ID 或用户名构造 cookie 名称),或者将所有 id/用户名存储在 cookie 中,然后检查每一个。

于 2013-10-28T14:53:36.923 回答
0

这个想法

将这两个 ID 存储在一个 cookie 中。当 cookie 是一个 ID 列表(例如逗号分隔)时,它可以对多个人进行投票限制。您必须检查尝试投票的人是否不在列表中。

当然,这仅在没有 ID 包含所选分隔符(在本例中为逗号)的假设下才有效。如果逗号不是这种情况,请选择竖线或任何满足此属性的字符。

算法

Cookie 机制旨在存储键值对。键和值都是字符串。如果您想在 cookie 中存储以逗号分隔的 ID 列表,则必须使用逗号作为分隔符 ( String.join(",", ids)) 将它们连接起来。首先读取 cookie 的原始值,将其拆分为逗号,然后添加新 ID(如果还没有),然后加入列表并更新 cookie。

执行

public void AddCookie() {
    HttpCookie MyCookie = new HttpCookie("MyCookie");
    var userName = Session["LoginPersonID"].ToString();
    var originalCookieContents = ViewData["CookieData"].ToString();
    var ids = new HashSet<String>(originalCookieContents.Split(','));
    ids.Add(userName);
    MyCookie.Value = String.Join(",", ids);
    MyCookie.Expires = DateTime.Now.AddDays(30);
    Response.Cookies.Add(MyCookie);
    ViewData["CookieData"] = MyCookie.Value;
}

不要忘记相应地更新您的视图代码!构造HashSetids 并使用它的Contains方法。

于 2013-10-28T14:52:50.140 回答
0

问题是您在命名 cookie 时不区分用户。每个用户应该有一个 cookie,或者您应该在该单个 cookie 中构建用户列表——但请记住,cookie 的大小限制为 4K。

所以如果你换行

HttpCookie MyCookie = new HttpCookie("MyCookie",
                      Session["LoginPersonID"].ToString()); 

像这样

var userName = Session["LoginPersonID"].ToString();
HttpCookie MyCookie = new HttpCookie("MyCookie-" + userName,
                      "Voted"); 

那么它应该可以工作(请记住,您还必须修改读取 cookie 的代码)。

于 2013-10-28T14:53:29.143 回答