一、基本登陆实现与验证码功能实现,该功能是和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. git 解决授权失败的方法

    git 提示  fatal: Authentication failed for 'http://***********‘’得解决方法 首先用 git config --list 查看一下 如果不对, ...

  2. JAVA判断是否是手机设备访问

    package com.common.util; import java.util.regex.Matcher;import java.util.regex.Pattern; /** * 检测是否为移 ...

  3. python 选课系统

    couser.py: import sys,osBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))sys.pa ...

  4. react使用create-react-app创建的项目部署

    一.在所有的项目代码编写完成后,react项目直接部署是无法正常访问的 1.问题一 网页无法正常的浏览器刷新,刷新会报404错,路由找不到页面 2.问题二 路由跳转后,浏览器后退按钮点击后,页面不刷新 ...

  5. HTML——HTML部分学习笔记

    1.前端工程师是干什么的?           PC页面         移动端页面 Web开发 = 前端开发 + 后台开发--->web应用(网站) 后台:数据 前台:负责数据展示 + 交互效 ...

  6. 接口自动化测试持续集成--Soapui接口测试

    接口测试目前笔者掌握的工具有三种: 一.python+requests+jenkins,优点:代码实现接口测试,对测试代码书写比较自由等:缺点:需要测试者需要有一定的代码基础: 二.jmeter+an ...

  7. 从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...

  8. ORA-12557协议适配器不可加载

    背景:以前电脑没有装ORACLE,仅是安装了简易客户端,此次想安装一个11g数据库,安装完成后用PLSQL登录,发现报错. 解决方案A:使用免安装的oracle客户端(instantclient_11 ...

  9. 在sparkStreaming实时存储时的问题

    1.实时插入mysql时遇到的问题,使用的updateStaeBykey有状态的算子 必须设置checkpoint  如果报错直接删掉checkpoint 在创建的时候自己保存偏移量即可 再次启动时读 ...

  10. [Offer收割] 编程练习赛1

    A HihoCoder 1268 九宫 思路: 一般类似于数独的题目都是使用回溯解决,这里由于题目数据较小同样可以直接DFS得出结果.这里我用了一个偷懒的方法(next_permutation),直接 ...