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

  我们的项目用到的一些 技术也跟大家提一下,主要是用了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. JavaScript进阶之路(一)初学者的开始

    一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...

  2. CSS3 3D立方体效果-transform也不过如此

    CSS3系列已经学习了一段时间了,第一篇文章写了一些css3的奇技淫巧,原文戳这里,还获得了较多网友的支持,在此谢过各位,你们的支持是我写文章最大的动力^_^. 那么这一篇文章呢,主要是通过一个3D立 ...

  3. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  4. 开源一个跨平台运行的服务插件 - TaskCore.MainForm

    本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.Main ...

  5. await and async

    Most people have already heard about the new “async” and “await” functionality coming in Visual Stud ...

  6. .NET Core 2016 回顾

    都在回顾自己的2016,今天我们来看看.NET Core的2016. 每一年的脚步的确是快,转眼间马上就2017.新的一年,带着理想和抱负继续出发. 1 月 ASP.NET 5 改名 ASP.NET ...

  7. 使用HttpClient的优解

    新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...

  8. springmvc 多数据源 SSM java redis shiro ehcache 头像裁剪

    获取下载地址   QQ 313596790  A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单;  技术:31359679 ...

  9. Postman - 功能强大的 API 接口请求调试和管理工具

    Postman 是一款功能强大的的 Chrome 应用,可以便捷的调试接口.前端开发人员在开发或者调试 Web 程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的 Fi ...

  10. Missing Push Notification Entitlement 问题

    最近打包上传是遇到一个问题: 描述: Missing Push Notification Entitlement - Your app includes an API for Apple's Push ...