登录 Cookie实现
Cookie判别登录状态
Cookie可以实现关闭浏览器再打开,还保留登录状态。
cookie存储登录信息的方式,需要保证数据不易被破解。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace UserLogin.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
//加入登录判断,如果username有值,就正常访问,否则跳转到登录页
if (Request.Cookies["u"]== null)
{
return Redirect("/home/loginpage");
}
else
{
return View();
}
}
public ActionResult LoginPage()
{
return View();
}
public JsonResult Login(string username)
{
//直接设置登录名的cookie,不验证密码
Response.Cookies.Add(new HttpCookie("u")
{
HttpOnly = true,
Expires = DateTime.Now.AddDays(1),
Value = username
});
return Json(new
{
message = "登录成功"
}, JsonRequestBehavior.AllowGet);
}
}
}
我们上面这种明文加密的方式是显然不可取的。 现实中我们使用Cookie储存用户登录凭证,都有验证数据是否伪造的能力。
换句话说,就是Cookie中存储的用户身份凭证信息,一定经过加密存储的,并且伪造的加密串可以被鉴别。
ASP.NET自带的身份凭证验证
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
namespace UserLogin.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
//加入登录判断,如果username有值,就正常访问,否则跳转到登录页
if (!User.Identity.IsAuthenticated)
{
//User.Identity.Name //用户名
return Redirect("/home/loginpage");
}
else
{
return View();
}
}
public ActionResult LoginPage()
{
return View();
}
public JsonResult Login(string username)
{
//直接设置登录名的cookie,不验证密码
FormsAuthentication.SetAuthCookie(username, true);
return Json(new
{
message = "登录成功"
}, JsonRequestBehavior.AllowGet);
}
}
}
loginUrl:登录页地址 name:cookie名 timeout:过期时间(分钟) slidingExpiration:是否自动续期
<system.web>
<authentication mode="Forms">
<forms loginUrl="/home/loginpage" name="WoDeShengFeng" timeout="60" slidingExpiration="true"></forms>
</authentication>
</system.web>
手动创建身份凭证Cookie
public JsonResult Login(string username)
{
//1.建立一个身份票据
// FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(username, true, FormsAuthentication.Timeout.Minutes);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2,username,DateTime.Now,DateTime.Now.Add(FormsAuthentication.Timeout), true, "管理员,会计");
//2.加密,获得加密后的字符串
var secretStr= FormsAuthentication.Encrypt(ticket);
//3.写入到cookie中
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName)
{
HttpOnly = true,
Path=FormsAuthentication.FormsCookiePath,
Expires= DateTime.Now.Add(FormsAuthentication.Timeout),
Value= secretStr
});
return Json(new
{
message = "登录成功"
}, JsonRequestBehavior.AllowGet);
}
ASP.NET Forms身份验证限制访问
将Home/Index的身份验证删除了
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
namespace UserLogin.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public ActionResult LoginPage()
{
return View();
}
public JsonResult Login(string username)
{
//1.建立一个身份票据
// FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(username, true, FormsAuthentication.Timeout.Minutes);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2,username,DateTime.Now,DateTime.Now.Add(FormsAuthentication.Timeout), true, "管理员,会计");
//2.加密,获得加密后的字符串
var secretStr= FormsAuthentication.Encrypt(ticket);
//3.写入到cookie中
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName)
{
HttpOnly = true,
Path=FormsAuthentication.FormsCookiePath,
Expires= DateTime.Now.Add(FormsAuthentication.Timeout),
Value= secretStr
});
return Json(new
{
message = "登录成功"
}, JsonRequestBehavior.AllowGet);
}
}
}
system.web配置节中可以设置授权
<authorization>
<!--允许匿名用户访问-->
<allow users="?"/>
<!--拒绝匿名用户-->
<deny users="?"/>
<!--允许所有用户访问-->
<allow users="*"/>
<!--拒绝所有用户访问-->
<deny users="*"/>
<!--允许admin和admin2访问-->
<allow users="admin,admin2"/>
<!--拒绝admin和admin2访问-->
<deny users="admin,admin2"/>
<!--允许角色为管理员和超级管理员的用户访问-->
<allow roles="管理员,超级管理员"/>
<!--拒绝角色为管理员和超级管理员的用户访问-->
<deny roles="管理员,超级管理员"/>
</authorization>
按照这个规则,我们还可以对特定目录或页面进行访问限制: configuration配置节下: path可以写路径或者具体页面
<location path="product">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
角色访问
https://www.cnblogs.com/pinko/archive/2013/05/02/3053965.html
要实现角色控制访问,需要自行进行用户身份的识别,自己去构建User身份信息。 Global.asax文件中:
protected void Application_AuthenticateRequest() {
var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
{
//从cookie中获取加密后的字符串
var secretStr=cookie.Value;
//根据字符串,调用Decrypt方法解密出票据
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(secretStr);
//判断是否过期
if (!ticket.Expired) {
//未过期,获取用户名和附加数据,并且建立角色的字符串数组
string username = ticket.Name;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
//建立身份凭据
GenericIdentity identity = new GenericIdentity(username);
GenericPrincipal principal = new GenericPrincipal(identity, roles);
//将用户身份设置到请求的上下文中
Context.User = principal;
}
}
}
练习
- 数据库建立:用户表,loginname,password,role;插入几条数据
- 做个登录页,实现登录功能
- User/Index 用户管理页,要求必须是管理员身份才能访问
- Product/Index 产品管理业,管理员和产品管理员都能访问
- 登录的时候,如果有ReturnUrl,那么登录完成后,跳转回ReturnUr指定的页面