好久没写随笔了,这段时间没 什么事情,领导 一直没安排任务,索性 一直在研究代码,说实在的,这个登录都 搞得我云里雾里的,所以这次我可能也讲得不是 特别清楚,但是 我尽力把我知道的讲出来,顺便也对自己最近的工作 做义工总结吧。

  我们的项目用到的一些 技术也跟大家提一下,主要是用了NHibernate,StructureMap,FluentHibernate等等,可能这篇文章我不会 全部 提到 ,不过相信后面,如果我要写文章的话,肯定是会提到的。我自己也模仿 了公司的框架做了一个 简单的登录(未完成)的,因为感觉公司的东西实在是很复杂,所以不一定可以完全消化,所以才 写了一上午没写完 = =

  首先,登录的话,我是写在一个Area里面,至于 怎么建立Area(区域)我就 不多累赘了,Area的名字我就 取成MS2Auth,因为 自己 喜欢MapleStory这个游戏,所以取了 它的 一个缩写 单词,以下是结构。

我们新建一个Controller名叫AccountController这个就是我们 登录用的主的控制器,然后再往Controller里面添加一些Action,比如我们添加一个LogOn的Action,代码如下:

        /// <summary>
/// 登录
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public ActionResult LogOn(MS2UserCheckTransferMsg message)
{
if (message.IsLogin)
{
return Json(new { Data=ShowpopupReminder(message)},JsonRequestBehavior.AllowGet);
} if (string.IsNullOrEmpty(message.Email))
{
ViewBag.ShowpopupReminder = ShowpopupReminder(message);
ViewBag.UserEmail = message.Email;
} var logOnModel = new LogOnModel(); if (Request.QueryString["GUID"] == "")
{
TempData["errorMessage"] = ErrorMessage;
}
else if (Request.QueryString["Reason"] == "NoCookie")
{
TempData["errorMessage"] = NoCookieErrMessage;
} if (User.Identity.IsAuthenticated)
{
return Redirect("~/LogOff.aspx");
} else
{
return View(logOnModel);
}
}

  大家 可能会先去关心MS2UserCheckTransferMsg这个类里面的东西。

    /// <summary>
/// 登陆检查
/// </summary>
public class MS2UserCheckTransferMsg:IMessage
{
public string Email { get; set; } public string password { get; set; } public bool IsLogin { get; set; } }

一个 是Email,一个 是密码,另一个 就是“是否登录”,是否登录 是检测 如果你访问到了这个ACTION的话,如果你 已经处于登录状态了,那么就会执行下面的流程。

这里面的一个 重点是 “反射”,通过反射 去获取某个类底下的方法。这个话 怎么 去理解 呢?首先大家主营到 下面的一个 方法。

        private bool ShowpopupReminder(MS2UserCheckTransferMsg message)
{
var queryBus = ObjectFactory.GetInstance<IQueryBus>();
return queryBus.Query<MS2UserCheckTransferMsg, dynamic>(message); }

  这里我们 通过 一个 工厂 方法去 得到IQueryBus的 一个 实例,然后 再用 这个实例反过来,去执行一个 Query的方法。

namespace YLW.MS2.Common.TransferMsg
{
public interface IQueryBus
{
TResponse Query<TRequest, TResponse>(TRequest message) where TResponse : class; }
}

  那么 ,这个IQueryBus其实是 一个 接口,我需要 得到这个接口的一个实例,该怎么 办呢?下面就提供了一种解决方法,大家想起来那个Global.asax文件了吗,那个不是 进行初始化的一个文件吗?对的,就是 这么一个文件,我们 需要 做的,就是 在Application_Start里面进行初始化,把这些 实例先一股脑的丢进去,进行工厂化处理,然后要的时候只要 指定实例名或者 类型的话,就可以 方便的取出来。

为此我们需要用到一个东西。那 就是StructureMap的For方法,来 注册这个接口的实例。

  

        public static void Init()
{
ObjectFactory.Configure(x =>
x.For<IQueryBus>().Use<LocalQueryBus>(););
}

  当然 ,这只是一个例子而已,具体的你 如果想注册其他的东西的话,也可以 用类似的方法去 写,大家 注意到 了没有 ,有 一个 叫做IMessage的接口,这个接口里面不 包含 任何东西,我的理解就是 这个接口的作用只是作为一个 中转而用的,另 一个接口 叫做IMessageHandler,这个 接口的话里面只有一个Execute方法。也就是下面要提到的,IMESSAGE只是 作为一个转换而已 ,也就是 说 任何 实现了IMessage接口的类,不需要实现任何多余的方法,也就是说,这个只是依赖注入的一个中转站而已(我个人的理解)。

  下面的方法就是通过反射区调用Execute方法,而这个Execuute方法真正 所在的类,其实是被IMessageHanlder所 实现的接口的一个 方法。

    public class LocalQueryBus:IQueryBus
{
public TResponse Query<TRequest, TResponse>(TRequest message) where TResponse : class
{
return (TResponse)QueryHandlerExecute((IMessage)message);
} private object QueryHandlerExecute(IMessage message)
{
var handlerType = typeof(IMessageHandler<>);
var genericType = handlerType.MakeGenericType(message.GetType()); var messageHandler = ObjectFactory.GetInstance(genericType); return messageHandler.GetType().GetMethod("Execute").Invoke(messageHandler, new object[] { message });
} }

下面 就说明了真正执行的方法的实际位置:

public class MS2UserCheckHandler: IMessageHandler<MS2UserCheckMessage>

  总之我感觉 这种 反射 跳来跳去的,我头都有点 花了,其中具体的用法具体去 考虑,比如 那个 MakeGenericType,大家可以自己 去 查查 用法 。

  由于有些 登录的机制特别的复杂,比如有你需要 一个“公共秘钥”去登录 ,就是说你 需要 返回 一个公共密码到另一台服务器上面 去,只有你的用户名和密码以及那个公共秘钥都对了,你才能登录,这个有点 类似于支付宝的数字证书吧,虽然 没 那么 复杂。那么,我们总不可能每次都去 匹配吧?这里告诉 大家 一个简单的方法,看下面的代码。

#if DEBUG
public ActionResult LogMeIn(LogOnModel model)
{
return RedirectToAction("Landing");
}
#endif

  大家只要 用#if DEBUG #endif 代码段,就可以调试本地的了,如果是服务器上的话,就不会执行本段代码 ,这段 代码只是在 本地启动的时候才有用哦。下面告诉 大家 一种伪造 登录的方法:可以使用Request.Headers.Add()方法去添加相应的键值对,比如 你 可以 往这里面 添加 用户名,EMAIL,公共秘钥ID等,如下面的代码 所示。

            Request.Headers.Add("SM_USER", user);
Request.Headers.Add("EMAIL", email);

  然后 进行本地调试的时候,只要把这些值取出来就行了,当然了,我这么做 也许有些人会说没意义,我的目的只是 为了模拟登录的流程而已,仅此而已。

  当然 ,你需要一个判断的过程,于是就有 了下面的方法:

        public CommandResponse Command<TRequest>(TRequest message)
{
var result = QueryHandlerExecute((IMessage)message); if (result!= null)
{
return (CommandResponse) result;
} return new CommandResponse();
}

  具体的我也说不清楚,这里面感觉 还是 有点 复杂。。。

 

    public class CommandResponse
{
public bool Success { get; set; } public string Message { get; set; }
}

  如果Success=true的话,那么就 使用下面这句话,这句话的作用就是使你的User.Identity.IsAuthenticated为True,表示 你已经通过了登录 验证。

FormsAuthentication.SetAuthCookie(model.MS2User, false);

  如果 你 没有通过验证的话,那么 还需要 往TempData里面去放一些值,跳转带到新页面 ,为什么 使用 TempData,因为登录后,错误 信息只显示一次 ,所以用TempData,当然如果 你是正常 退出的话,那么就 可以 这样 。

                System.Web.HttpContext.Current.Session.RemoveAll();
FormsAuthentication.SignOut();
return RedirectToAction("LogOn", "Account", new
{
area = "MS2Auth"
});

注意 在 这里 area是必须的,因为 我们把登录的接口 放到了Area里面。好久没写了,文字比较拙劣,今天试着做了下登录,没 完全做出来,希望以后能有 进一步的提高吧。

 PS:差点 忘了贴登录的View页面,比较简单。

@using System.Configuration
@using YLW.MS2.Common
@using StructureMap
@model YLW.MS2.Web.Models.LogOnModel @{
ViewBag.Title = "LogOn";
Layout = "~/Views/Shared/_Layout.cshtml";
} <div class="error-container">
<ul>
@Html.ValidationSummary(true,"登录失败!请检查!")
@if (TempData.ContainsKey("errorMessage"))
{
Html.Raw(TempData["errorMessage"].ToString());
}
@if (ViewData.ContainsKey("errorMessage"))
{
Html.Raw(ViewData["errorMessage"].ToString());
}
</ul> </div> <form name="login" id="login" method="post" action="@Url.Action("LogMeIn", "Account", new { area="MS2Auth"})"> <div>
@Html.TextBoxFor(m=>m.UserName)
@Html.ValidationMessageFor(m=>m.UserName)
</div> <div>
@Html.PasswordFor(m=>m.Password)
@Html.ValidationMessageFor(m=>m.Password) </div> <div>
<button type="submit" class="button" onclick="CheckUser();return false" value="Log In"></button> </div> </form> <script type="text/javascript">
function CheckUser()
{
$.ajax({
type: "POST",
url: "@Url.Action("LogOn","Account")",
data: { Email: $("#UserName").val(), password: $("#Password").val(), IsLogin: 'true' },
dataType: "text json",
crossDomain: false,
cache: false,
async: true,
success: function (result) {
if (result.Data) { }
else
{ } } }); } </script>

  里面很 简单,就是一个 提交表单,其中注意一下 如果 是自己DEBUG环境的话,记得吧把 IsLogin设为TRUE,当然,这个是暂时的。

ASP.NET MVC 登录验证的更多相关文章

  1. ASP.NET MVC Model验证(四)

    ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...

  2. ASP.NET MVC Model验证(三)

    ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...

  3. ASP.NET MVC Model验证(一)

    ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...

  4. 【MVC】ASP.NET MVC Forms验证机制

    http://www.cnblogs.com/bomo/p/3309766.html 随笔 - 121  文章 - 0  评论 - 92 [MVC]ASP.NET MVC Forms验证机制 ASP. ...

  5. 通过扩展改善ASP.NET MVC的验证机制[使用篇]

    原文:通过扩展改善ASP.NET MVC的验证机制[使用篇] ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有 ...

  6. Asp.Net MVC 身份验证-Forms

    Asp.Net MVC 身份验证-Forms 在MVC中对于需要登录才可以访问的页面,只需要在对应的Controller或Action上添加特性[Authorize]就可以限制非登录用户访问该页面.那 ...

  7. ASP.NET MVC自定义验证Authorize Attribute(包含cookie helper)

    前几天Insus.NET有在数据库实现过对某一字段进行加密码与解密<使用EncryptByPassPhrase和DecryptByPassPhrase对MS SQLServer某一字段时行加密和 ...

  8. ASP.NET MVC Model验证(五)

    ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...

  9. ASP.NET MVC Model验证(二)

    ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...

随机推荐

  1. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  2. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  3. 细说前端自动化打包工具--webpack

    背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...

  4. async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  5. 【.net 深呼吸】跨应用程序域执行程序集

    应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...

  6. UWP开发必备以及常用知识点总结

    一直在学UWP,一直在写Code,自己到达了什么水平?还有多少东西需要学习才能独挡一面?我想对刚接触UWP的开发者都有这种困惑,偶尔停下来总结分析一下还是很有收获的! 以下内容是自己开发中经常遇到的一 ...

  7. C# await和async

    基础阅读:http://www.cnblogs.com/jesse2013/p/async-and-await.html 答疑阅读:http://www.cnblogs.com/heyuquan/ar ...

  8. UML图中经常用到几种的关系图例

    学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...

  9. javascript 笔记!

    1.通过javascript向文档中输出文本 document是javascript的内置对象,代表浏览器的文档部分 document.write("Hello Javascript&quo ...

  10. 开始mono开发

    使用mono框架开发android程序,第一步当然是构建开发环境,严格意义上说是使用 mono for android开发android程序. 参考Mono for Android安装配置破解  mo ...