一、基本登陆实现与验证码功能实现,该功能是和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. 60道Python面试题&答案精选!找工作前必看

    需要Word/ PDF版本的同学可以在实验楼微信公众号回复关键词"面试题"获取. 1. Python 的特点和优点是什么? 答案:略. 2. 什么是lambda函数?它有什么好处? ...

  2. Oracle控制文件冗余

    1.备份参数文件.检查控制文件.检查磁盘组名 sqlplus / as sysdba !echo "create pfile='$HOME/pfile_$ORACLE_SID_`date + ...

  3. Mac截图操作,自定义快捷键

    选择system preferences 下面能看到系统定义的快捷键,可以自己修改

  4. python装饰器扩展之functools.wraps

    我们知道函数被装饰器,装饰后,所有的属性,以及内置函数就失效了. 原因是函数类型变成了warpper类型 示例1:不带wraps装饰器示例 def warfunc(func): def warpper ...

  5. #WEB安全基础 : HTTP协议 | 0x9 GET和POST请求以及请求URI的方式

    请求URI的方式 1.URI为完整的请求URI GET http://hackr.jp/index.htm HTTP/1.1 2.在首部字段Host中写明域名或IP地址 GET/index.htm H ...

  6. python数据类型之元组类型

    #为何要有元组,存放多个值,元组不可变,更多的是用来做查询 t=(1,[1,2,3],'a',(1,2)) #t=tuple((1,[1,2,3],'a',(1,2))) # print(type(t ...

  7. py001

       pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple -------------------------------- ...

  8. 灵雀云:etcd 集群运维实践

    [编者的话]etcd 是 Kubernetes 集群的数据核心,最严重的情况是,当 etcd 出问题彻底无法恢复的时候,解决问题的办法可能只有重新搭建一个环境.因此围绕 etcd 相关的运维知识就比较 ...

  9. [Docker] sh: docker-compose: not found

    有点坑爹,在使用  alpine 镜像的时候,明明在里面安装了docker-compose,/usr/local/bin/docker-compose也是存在的,却报 sh: docker-compo ...

  10. [NOIP2017赛前复习第二期]复赛考试技巧与模版-普及组

    考试技巧 1.拿到考卷首先通看题目,按自己感觉的难度排序(普及一般是1-2-3-4了~还是相信出题人不会坑我们的2333) 2.一般来说,普及组前两道题比较简单(大水题啊233~),但是通常坑很多,例 ...