一、基本登陆实现与验证码功能实现,该功能是和spring.net功能集合使用的,因为后面要用到验证是否处于登陆状态

1. 先构建一个登陆页面

 @{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>XX商城后台管理系统登录</title>
<script type="text/javascript">
if (window.parent.window != window) {
window.top.location.href = "/Home/CheckLogin";
}
</script>
<script src="~/Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
@* <script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>*@
<script src="~/Scripts/jquery.validate.min.js"></script>
@*<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>*@
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> @*ajax登录*@
<script type="text/javascript">
function changeCheckCode() {
//为图片加一个src参数,向其后追加一个1,比如现在是src=“a1”,点击一次就是a11
$("#img").attr("src", $("#img").attr("src") + );
}
function afterLogin(data) {
var serverData = data.split(':');
if (serverData[] == "ok") {
//页面跳转一下
window.location.href = "/Home/Index"
} else {
$("#errorMsg").css("display", "block");
$("#errorMsg").text(serverData[]);
changeCheckCode(); //让验证码切换一下
}
}
</script>
<style type="text/css">
* {
padding: ;
margin: ;
}
body {
text-align: center;background: #4974A4;
}
#login {
width: 740px; margin: auto;font-size: 12px;
}
#loginlogo {
width: 700px; height: 100px; overflow: hidden;background: url('/Content/Images/login/logo.png') no-repeat; margin-top: 50px;
}
#loginpanel {
width: 729px;
position: relative;
height: 300px;
}
.panel-h {
width: 729px;
height: 20px;
background: url('/Content/Images/login/panel-h.gif') no-repeat;
position: absolute;
top: 0px;
left: 0px;
z-index: ;
}
.panel-f {
width: 729px;
height: 13px;
background: url('/Content/Images/login/panel-f.gif') no-repeat;
position: absolute;
bottom: 0px;
left: 0px;
z-index: ;
}
.panel-c {
z-index: ;
background: url('/Content/Images/login/panel-c.gif') repeat-y;
width: 729px;
height: 300px;
}
.panel-c-l {
position: absolute;
left: 60px;
top: 40px;
}
.panel-c-r {
position: absolute;
right: 20px;
top: 50px;
width: 222px;
line-height: %;
text-align: left;
}
.panel-c-l h3 {
color: #556A85;
margin-bottom: 10px;
}
.panel-c-l td {
padding: 7px;
}
.login-text {
height: 24px;
left: 24px;
border: 1px solid #e9e9e9;
background: #f9f9f9;
}
.login-text-focus {
border: 1px solid #E6BF73;
}
.login-btn {
width: 114px;
height: 29px;
color: #E9FFFF;
line-height: 29px;
background: url('/Content/Images/login/login-btn.gif') no-repeat;
border: none;
overflow: hidden;
cursor: pointer;
}
#txtUsername, #code, #txtPassword {
width: 191px;
}
#logincopyright {
text-align: center;
color: White;
margin-top: 50px;
}
a {
color: Black;
}
a:hover {
color: Red;
text-decoration: underline;
}
</style>
</head>
<body style="padding: 10px">
<div id="login">
<div id="loginlogo">
</div>
<div id="loginpanel">
<div class="panel-h">
</div>
<div class="panel-c">
<div class="panel-c-l"> @*请求地址,控制器名 参数为null 请求方式 返回函数 加载执行时动画 表单id的值 *@
@using (Ajax.BeginForm("UserLogin", "Login", new { }, new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterLogin", LoadingElementId = "div1" }, new { id = "loginForm" }))
{
<table cellpadding="" cellspacing="">
<tbody>
<tr>
<td align="left" colspan="">
<h3>
请使用ItcastOA管理系统账号登录
</h3>
</td>
</tr>
<tr>
<td align="right">
账号:
</td>
<td align="left">
<input type="text" name="LoginCode" id="LoginCode" class="login-text" />
</td>
</tr>
<tr>
<td align="right">
密码:
</td>
<td align="left">
<input type="password" name="LoginPwd" id="LoginPwd" value="" class="login-text" />
</td>
</tr>
<tr>
<td>
验证码:
</td>
<td align="left">
<input type="text" class="login-text" id="code" name="vCode" value="" />
</td>
</tr>
<tr>
<td></td>
<td>
<img id="img" src="/Login/ShowValidateCode?id=1" style="float: left; height: 24px;" />
<div style="float: left; margin-left: 5px; margin-top: 10px;">
<a href="javascript:void(0)" onclick="changeCheckCode();return false;">看不清,换一张</a>
</div>
</td>
</tr>
<tr>
<td align="center" colspan="">
<input type="submit" id="btnLogin" value="登录" class="login-btn" /><span id="errorMsg" style="font-size:14px;color:red;display:none"></span>
<div id="div1" style="display:none">正在登录,请稍后....</div>
</td>
</tr>
</tbody>
</table>
}
</div>
<div class="panel-c-r">
<p>
请从左侧输入登录账号和密码登录
</p>
<p>
如果遇到系统问题,请联系网络管理员。
</p>
<p>
如果没有账号,请联系网站管理员。
</p>
<p>
......
</p>
</div>
</div>
<div class="panel-f">
</div>
</div>
<div id="logincopyright">
Copyright ? itcast.com
</div>
</div>
</body>
</html>

2、 封装一个生成验证码的文件,放置在Common文件夹下,引用dll文件system.Drawing。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web; namespace Common
{
public class ValidateCode
{
public ValidateCode()
{
}
/// <summary>
/// 验证码的最大长度
/// </summary>
public int MaxLength
{
get { return ; }
}
/// <summary>
/// 验证码的最小长度
/// </summary>
public int MinLength
{
get { return ; }
}
/// <summary>
/// 生成验证码
/// </summary>
/// <param name="length">指定验证码的长度</param>
/// <returns></returns>
public string CreateValidateCode(int length)
{
int[] randMembers = new int[length];
int[] validateNums = new int[length];
string validateNumberStr = "";
//生成起始序列值
int seekSeek = unchecked((int)DateTime.Now.Ticks);
Random seekRand = new Random(seekSeek);
int beginSeek = (int)seekRand.Next(, Int32.MaxValue - length * );
int[] seeks = new int[length];
for (int i = ; i < length; i++)
{
beginSeek += ;
seeks[i] = beginSeek;
}
//生成随机数字
for (int i = ; i < length; i++)
{
Random rand = new Random(seeks[i]);
int pownum = * (int)Math.Pow(, length);
randMembers[i] = rand.Next(pownum, Int32.MaxValue);
}
//抽取随机数字
for (int i = ; i < length; i++)
{
string numStr = randMembers[i].ToString();
int numLength = numStr.Length;
Random rand = new Random();
int numPosition = rand.Next(, numLength - );
validateNums[i] = Int32.Parse(numStr.Substring(numPosition, ));
}
//生成验证码
for (int i = ; i < length; i++)
{
validateNumberStr += validateNums[i].ToString();
}
return validateNumberStr;
}
/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="context">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public void CreateValidateGraphic(string validateCode, HttpContext context) //使用HttpContext必须引用system.web,是引入而不是导入
{
Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), );
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色
g.Clear(Color.White);
//画图片的干扰线
for (int i = ; i < ; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new Font("Arial", , (FontStyle.Bold | FontStyle.Italic));
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(, , image.Width, image.Height),
Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateCode, font, brush, , );
//画图片的前景干扰点
for (int i = ; i < ; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//画图片的边框线
g.DrawRectangle(new Pen(Color.Silver), , , image.Width - , image.Height - );
//保存图片数据
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
//输出图片流
context.Response.Clear();
context.Response.ContentType = "image/jpeg";
context.Response.BinaryWrite(stream.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
/// <summary>
/// 得到验证码图片的长度
/// </summary>
/// <param name="validateNumLength">验证码的长度</param>
/// <returns></returns>
public static int GetImageWidth(int validateNumLength)
{
return (int)(validateNumLength * 12.0);
}
/// <summary>
/// 得到验证码的高度
/// </summary>
/// <returns></returns>
public static double GetImageHeight()
{
return 22.5;
} //C# MVC 升级版
/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public byte[] CreateValidateGraphic(string validateCode)
{
Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), );
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色
g.Clear(Color.White);
//画图片的干扰线
for (int i = ; i < ; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new Font("Arial", , (FontStyle.Bold | FontStyle.Italic));
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(, , image.Width, image.Height),
Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateCode, font, brush, , );
//画图片的前景干扰点
for (int i = ; i < ; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//画图片的边框线
g.DrawRectangle(new Pen(Color.Silver), , , image.Width - , image.Height - );
//保存图片数据
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
//输出图片流
return stream.ToArray();
}
finally
{
g.Dispose();
image.Dispose();
}
}
}
}

3. 后端代码实现完成用户登录与验证码功能实现。

 using BLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace OA_MVC.Controllers
{
public class LoginController : Controller
{
//
// GET: /Login/ public ActionResult Index()
{
return View();
}
IBLL.IUserInfoService UserInfoService { get; set; }
#region 完成用户登录
public ActionResult UserLogin()
{
//判断验证码是否正确
string validateCode = Session["validateCode"] != null ? Session["validateCode"].ToString() : string.Empty;
if (string.IsNullOrEmpty(validateCode)) //如果等于null
{
return Content("no:验证码错误!!");
}
Session["validateCode"] = null;
string txtCode = Request["vCode"];
//如果验证码不相等
if (!validateCode.Equals(txtCode, StringComparison.InvariantCultureIgnoreCase))
{
return Content("no:验证码错误!!");
}
string userName = Request["LoginCode"];
string userPwd = Request["LoginPwd"];
var userInfo = UserInfoService.LoadEntities(u => u.UName == userName && u.UPwd == userPwd).FirstOrDefault();//根据用户名找用户
if (userInfo != null)
{
Session["userInfo"] = userInfo;
////产生一个GUID值作为Memache的键.
//// System.Web.Script.Serialization.JavaScriptSerializer
//string sessionId = Guid.NewGuid().ToString();
//Common.MemcacheHelper.Set(sessionId, Common.SerializeHelper.SerializeToString(userInfo)
// , DateTime.Now.AddMinutes(20));//将登录用户信息存储到Memcache中。
//Response.Cookies["sessionId"].Value = sessionId;//将Memcache的key以Cookie的形式返回给浏览器。
return Content("ok:登录成功");
}
else
{
return Content("no:登录失败");
}
}
#endregion
#region 显示验证码
public ActionResult ShowValidateCode()
{
Common.ValidateCode vliateCode = new Common.ValidateCode();
string code = vliateCode.CreateValidateCode();//产生验证码,4位数的验证码
Session["validateCode"] = code; //存在session中进行校验
byte[] buffer = vliateCode.CreateValidateGraphic(code);//将验证码画到画布上.
return File(buffer, "image/jpeg"); //向浏览器返回一个文件
}
#endregion
}
}

4. config文件夹中的controllers.xml文件中,加入以下代码,作用是为该类中的UserInfoService属性赋值。 相关spring.net知识点请参考https://www.cnblogs.com/wangjinya/p/10706744.html

 <object  type="CZBK.ItcastOA.WebApp.Controllers.LoginController, CZBK.ItcastOA.WebApp" singleton="false" >
<property name="UserInfoService" ref="UserInfoService" />
</object>

5. 方法过滤器,

5.1 新建一个base控制器,该控制器主要用来把执行过程从中间切割,让每一次执行,都会执行该方法,OnActionExecuting方法是提供的一个类,每次执行就会先执行该方法。

     public class BaseController : Controller
{
//
// GET: /Base/ /// <summary>
/// 方法过滤器,执行控制器中的方法之前先执行该方法。
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (Session["userInfo"] == null)
{
// filterContext.HttpContext.Response.Redirect("/Login/Index");
//            因为在返回的切片处理的过程中,之前的函数必须返回一个Result类型的试图过去,所以,以上方法不能满足,只能使用以下方法
//返回一个ActionResult类型的Redirect,继承该类的类就不会去执行本身的Redirect,需要使用下面的方法,而不是上面的方法
filterContext.Result = Redirect("/Login/Index");
}
}
}
}

5.2 让每一个控制器继承该控制器的类名

   public class LoginController : BaseController //Controller
{
//
// GET: /Login/ public ActionResult Index()
{
return View();
}
}

MVC基本登陆与验证码功能实现的更多相关文章

  1. JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客

    JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客https://blog.csdn.net/KooKing_L/article/details/79711379

  2. 一步一步实现web程序信息管理系统之三----登陆业务逻辑实现(验证码功能+参数获取)

    本篇紧接着上一篇文章[一步一步实现web程序信息管理系统之二----后台框架实现跳转登陆页面] 验证码功能 一般验证码功能实现方式为,前端界面访问一个url请求,后端服务代码生成一个图片流返回至浏览器 ...

  3. javaweb实现验证码功能

    在javaweb的用户注册与登陆功能时,有时为了防止漏洞或者大量注册,可以使用验证码功能,下面是验证码的一个简单实现 验证码类 public class ValiImg extends HttpSer ...

  4. Tornado框架实现图形验证码功能

    图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...

  5. .NET Core实战项目之CMS 第十六章 用户登录及验证码功能实现

    前面为了方便我们只是简单实现了基本业务功能的增删改查,但是登录功能还没有实现,而登录又是系统所必须的,得益于 ASP.NET Core的可扩展性因此我们很容易实现我们的登录功能.今天我将带着大家一起来 ...

  6. JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)

    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架) 本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦. 先把实现的发送邮箱验证码更能更新了. 老规矩,更多内容在注释 ...

  7. php CI框架实现验证码功能和增强验证码安全性实战教程

    php CI框架实现验证码功能和增强验证码安全性实战教程 CodeIgniter简称CI是最流行的一个php MVC框架之一,本人讲从实际项目使用中写系列实战经验,有别与其他的理论讲解文章,会附上实战 ...

  8. django验证码功能

    1.目的 现在我们一般访问网页都需要输入验证码,比如博客园,有的甚至是通过手机验证码实时登录.这样做的目的主要还是为了防止其他人的恶意访问,比如爬虫,下面就来看看验证码是如何实现的 2.StringI ...

  9. Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现

    本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础. 为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是“Com ...

随机推荐

  1. xamarin.forms 动态条件更换数据模板

    解决方案1:  https://oren.codes/2014/12/31/datatemplateselector-for-xamarin-forms/ 解决方案2:  https://docs.m ...

  2. c#十进制转二进制算法 和字符串反转算法

    去某软面试 面试官给个题上黑板做,写个算法 求95转2进制后1的个数. 我在黑板上敲了 static int count = 0; /// <summary> /// 获取10进制数转2进 ...

  3. VS2017 + EF6连接MySql

    VS2017 + EF6连接MySql   原地址:https://blog.csdn.net/mzhifa/article/details/80999105 VS2017 + EF6连接MySql ...

  4. matlab多个曲面如何画在一个坐标系中的疑问

    matlab多个曲面如何画在一个坐标系中的疑问 [复制链接] [X,Y]=meshgrid(-3:0.1:3);Z=X.^2+Y.^2;mesh(X,Y,-Z)hold onmesh(X,Y,Z)

  5. Kafka笔记8(管理Kafka)

    使用kafka-topic.sh工具可以执行大部分操作   创建/修改/删除/查看集群里的主题.要使用全部功能,需要通过--zookeeper参数提供zookeerper连接字符串 创建主题: 创建主 ...

  6. Asp.net Image控件显示Bitmap生成图像

    from:https://blog.csdn.net/qq_29011299/article/details/81137980 using(Bitmap bmp=new Bitmap(300,50)) ...

  7. MySql 版本

    MySql 版本: netformwork 2.0 netformwork 4.0

  8. get_class __class__ get_called_class 分析记录

    首先看代码: class A { use T { T::say as aTsay; } public function say() { echo 'a__class__:' . __CLASS__ . ...

  9. POJ滑雪

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 97172   Accepted: 36843 Description ...

  10. MMIO和PIO

    1.概念 内存映射I/O(MMIO)[统一编址]和端口映射I/O(PMIO)[独立/单独编址]是两种互为补充的I/O方法,用于设备驱动程序和设备通信,即在CPU和外部设备之间. (1)在MMIO中,内 ...