统一登录验证:
1、定义实体类Person:利用特性标签验证输入合法性设计登录页面
1
2
3
4
5
6
7
8
9
|
public class Person
{ [DisplayName( "用户名" ), Required(ErrorMessage = "账户非空!" )]
public string LoginName { get ; set ; }
[DisplayName( "密 码" ), Required(ErrorMessage = "密码非空!" )]
public string Password { get ; set ; }
[DisplayName( "验证码" ), Required(ErrorMessage = "验证码非空!" )]
public string Vcode { get ; set ; }
} |
2、设计验证码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
public class VcodeController : Controller
{ //
// GET: /Vcode/
public ActionResult Vcode()
{
byte [] buffer;
string str = GetRdStr(5);
//将生成随机字符串存入session中
Session[ "vcode" ] = str;
using (Image img= new Bitmap(80,30))
{
using (Graphics g=Graphics.FromImage(img))
{
//清除背景色
g.Clear(Color.White);
g.DrawRectangle(Pens.Black, 0, 0, img.Width - 1, img.Height - 1);
DrawLines(50, img, g);
g.DrawString(str, new Font( "微软雅黑" , 16), Brushes.Black, 0, 0);
DrawLines(35, img, g);
}
using (System.IO.MemoryStream ms= new System.IO.MemoryStream())
{
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
buffer=ms.ToArray();
}
}
return File(buffer, "image/jpeg" );
}
/// <summary>
/// 定义随机对象
/// </summary>
Random rd = new Random();
/// <summary>
/// 生产指定长度随机字符串
/// </summary>
/// <returns>随机字符串</returns>
string GetRdStr( int count)
{
string str = "abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ23456789" ;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for ( int i=0;i<count;i++)
{
sb.Append(str[rd.Next(str.Length)]);
}
return sb.ToString();
}
/// <summary>
/// 绘制指定数量干扰线
/// </summary>
/// <param name="count">数量</param>
/// <param name="img">图片对象</param>
/// <param name="g">画家对象</param>
void DrawLines( int count,Image img,Graphics g)
{
for ( int i=0;i<count;i++)
{
Point p1 = new Point(rd.Next(img.Width - 1), rd.Next(img.Height - 1));
Point p2 = new Point(p1.X + rd.Next(-1, 2), p1.X + rd.Next(-1, 2));
g.DrawLine(Pens.AliceBlue, p1, p2);
}
}
} |
3、设计登录页面,并写入登录逻辑
前台页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
@{ ViewBag.Title = "Login";
} @using 统一登录2.Models @model Person < script src = "~/Scripts/jquery.validate.js" ></ script >
< script src = "~/Scripts/jquery.validate.unobtrusive.js" ></ script >
@using (@Html.BeginForm("Login", "Login", FormMethod.Post)) { < table >
< tr >
< th >@Html.DisplayNameFor(p => p.LoginName)</ th >
< td >
@Html.TextBoxFor(p => p.LoginName)
@Html.ValidationMessageFor(p => p.LoginName)
</ td >
</ tr >
< tr >
< th >@Html.DisplayNameFor(p => p.Password)</ th >
< td >
@Html.PasswordFor(p => p.Password)
@Html.ValidationMessageFor(p => p.Password)
</ td >
</ tr >
< tr >
< th >@Html.DisplayNameFor(p => p.Vcode)</ th >
< td >
@Html.TextBoxFor(p => p.Vcode)
< img src = "@Url.Action(" Vcode", "Vcode")" />
@Html.ValidationMessageFor(p => p.Vcode)
</ td >
</ tr >
< tr >
< th ></ th >
< td >
< input type = "submit" value = "登录" />
</ td >
</ tr >
</ table >
} < script type = "text/javascript" >
</ script >
|
后台逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class LoginController : Controller
{ //
// GET: /Login/
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Person model)
{
//判断实体验证是否成功
if (ModelState.IsValid == false )
{
ModelState.AddModelError( "" , "实体验证失败!" );
return View();
}
//判断验证码验证是否成功
if (Session[ "vcode" ]!= null &&Session[ "vcode" ].ToString().Equals(model.Vcode,StringComparison.OrdinalIgnoreCase))
{
ModelState.AddModelError( "" , "验证码输入不正确!" );
return View();
}
//判断账户密码验证是否成功
if (model.LoginName!= "admin" ||model.Password!= "123" )
{
ModelState.AddModelError( "" , "用户名或密码错误!" );
return View();
}
//登录成功,登录信息存入Session
Session[ "uInfo" ] = model;
//跳转到主页面
return RedirectToAction( "Index" , "Home" );
}
} |
4、在过滤器中写入统一验证逻辑--注:这里用标签来判断是否需要进行登录验证,标签类实在第五步定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public override void OnActionExecuting(ActionExecutingContext filterContext)
{ //判断是否需要登录验证
if (filterContext.ActionDescriptor.IsDefined( typeof (IgnoreLoginAttribute), false ))
{
return ;
}
if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined( typeof (IgnoreLoginAttribute), false ))
{
return ;
}
//根据Session进行登录验证
if (filterContext.HttpContext.Session[ "uInfo" ]== null )
{
//1.Ajax请求
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
JsonResult jsonView = new JsonResult();
jsonView.ContentType = "application/json" ;
jsonView.Data = new {status=2,msg= "未登录" };
jsonView.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
filterContext.Result = jsonView;
}
//2.一般请求
else
{
ContentResult contentView = new ContentResult();
contentView.Content = "<script>window.alert('您还没有登录!请重新登录...');window.location='/Login/Login'</script>" ;
filterContext.Result = contentView;
}
}
} |
5、定义自定义特性标签,不需要登录验证统一贴上特性标签
1
2
3
4
5
6
7
|
/// <summary> /// 是否忽略登录验证特性标签 /// </summary> [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple= false )]
public class IgnoreLoginAttribute:Attribute
{ } |