我正在尝试在用户登录时创建一个持久性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
答案 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来自同一时间......