为什么我的cookie没有删除?

时间:2015-09-14 18:36:40

标签: asp.net asp.net-mvc cookies

我正在尝试在用户登录时创建一个持久性cookie(不使用内置身份验证)。

我能做到这一点的唯一方法是创建一个有效期限设置为DateTime.Now.AddYears(1)的cookie

由于我想允许用户注销,因此我在登录表单后面的每个页面的布局上都有一个注销按钮。

此注销按钮如下所示:

<li>@Html.ActionLink("Log Out", "Logout", "Home")</li>

令我感到困惑的是,这段代码没有从浏览器中删除cookie。它将我带回登录表单,但我仍然可以轻松导航回受保护的页面,它仍然会记住我基于之前登录的人。

这是我的代码:

    [AllowAnonymous]
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Login(User model)
    {
        try
        {
            DoLogin(model.EmailAddress, model.Password);
            return Json(new
            {
                Message = "Success",
                IsOK = bool.TrueString
            });
        }
        catch (Exception ex)
        {
            SendError("/", ex);
            return ReportError(ex, "USER LOGIN");
        }
    }

    private void DoLogin(string EmailAddress, string Password)
    {
        var user = db.Users.Include("UserRole").FirstOrDefault(x => x.EmailAddress == EmailAddress);

        if (Hashing.ValidatePassword(Password, user.Password))
            generateCookie(user);
    }

    private void generateCookie(Models.User u)
    {
        HttpCookie userCookie = new HttpCookie("Ortund");
        userCookie.Values["userid"] = Convert.ToString(u.Id);
        userCookie.Values["fname"] = u.FirstName;
        userCookie.Values["lname"] = u.LastName;
        userCookie.Values["role"] = u.UserRole.RoleName;
        userCookie.Expires = DateTime.Now.AddYears(1);
        Response.Cookies.Add(userCookie);
    }

那为什么不清理我的饼干?

修改

所以现在我根据问题答案中的建议修改了我的代码(见下文)。

我在我的控制器上添加了一个Logout Action并执行了此操作:

    public ActionResult Logout()
    {
        Session.Clear();
        HttpCookie userCookie = new HttpCookie("Ortund");
        userCookie.Expires = DateTime.Now.AddYears(-1);
        Response.Cookies.Add(userCookie);

        return View("Index");
    }

虽然我的登录似乎仍然正常,但Request Cookie未使用新的登录详细信息进行更新。这是我登录后的样子:

    Request.Cookies["Ortund"] {System.Web.HttpCookie} System.Web.HttpCookie  
    Domain null string  
    Expires {0001-01-01 12:00:00 AM} System.DateTime  
    HasKeys true bool  
    HttpOnly false bool  
    Name "Ortund" string  
    Path "/" string  
    Secure false bool  
    Shareable false bool

2 个答案:

答案 0 :(得分:3)

您需要将过期的cookie写入响应,而不是读取并将其设置回请求。

var cookie = Request.Cookies["Ortund"];
cookie.Expires = DateTime.Now.AddSeconds(-1);
Response.Cookies.Add(cookie);

我会在how to implement Forms Authentication in c#上做一些阅读。这将为您提供一个更好的起点,然后尝试推出自己的身份验证cookie,这将导致安全漏洞。标准表单身份验证已经提供了很多功能,并提供了一个简单的API来访问它,包括加密故障单,提供身份信息等方法。

或者您也可以查看asp.net identity。这是Microsoft管理身份和提供身份验证和授权的最新API。它还与SSO集成,例如使用Facebook或Microsoft身份存储来验证用户。

编辑 - 根据更多信息请求

以下是一些使用基本内置asp.net表单身份验证的示例代码。这个例子是基于cookie的。您还需要配置web.config以使用它。完成后,其余部分会自动发生,您可以随时使用HttpContext.User.Identity.获取用户的信息。在web.config中,您还需要添加解密和验证密钥。

public sealed class AuthController : Controller
{
    [AllowAnonymous] // get the view to login
    public ActionResult Login()
    {
        return View();
    }
    [HttpPost]
    [AllowAnonymous] // execute a login post
    public ActionResult ExecuteLogin(LoginModel model)
    {
        // validate credentials
        var ticket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddHours(3), model.RememberMe, /*anything else you want stored in the ticket*/ null);
        var encryptedTicket = FormsAuthentication.Encrypt(ticket);
        var isSsl = Request.IsSecureConnection; // if we are running in SSL mode then make the cookie secure only

        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
        {
            HttpOnly = true, // always set this to true!
            Secure = isSsl,
        };

        if (model.RememberMe) // if the user needs to persist the cookie. Otherwise it is a session cookie
            cookie.Expires = DateTime.Today.AddMonths(3); // currently hard coded to 3 months in the future

        Response.Cookies.Set(cookie);

        return View(); // return something
    }
    [Authorize] // a secured view
    public ActionResult SecuredView() {
        return View();
    }
    [Authorize] // log the user out
    public ActionResult Logout()
    {
        System.Web.Security.FormsAuthentication.SignOut();
        return RedirectToAction("Index", "Home");
    }
}

这是web.config的更改

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
... 
  <system.web>
    <authentication mode="Forms">
      <forms name="myAuthCookie" ticketCompatibilityMode="Framework40" cookieless="UseCookies" requireSSL="false" timeout="180" protection="Encryption" />
    </authentication>
    <machineKey decryption="AES" decryptionKey="key here" validation="HMACSHA256" validationKey="validation key here" />
  </system.web>
</configuration>

答案 1 :(得分:2)

您需要再次将cookie写入浏览器

HttpCookie userCookie = new HttpCookie("Ortund");
userCookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(userCookie);

而不仅仅是

Request.Cookies["Ortund"].Expires = DateTime.Now.AddSeconds(1);

一个很好的解释为什么,it's in my own answer来自同一时间......