• asp.net mvc实现系统登录及验证功能


    1、常见的应用场景

    在网上购物或者实际的使用过程中经常遇到这样的一个场景:你必须输入用户米/密码,进行登录。登录完成后,界面自动跳转到之前的界面或者主页。具体下面的三个图所示。
    商品的列表
    登录的界面
    商品的列表或下一步操作

    2、ASP.NET MVC的实现

    在ASP.NET MVC中有个功能是身份认证(就是使用用户名和密码登录的问题),以及使用角色登录的功能。
    具体代码如下:

    2.1 商品列表的代码

    点击商品列表中的购买本商品,界面会进行跳转。界面的代码如下所示:

    <h2>商品列表</h2>
    
    <table>
        <tr>
            <td>商品名称</td>
            <td>价格</td>
            <td>操作</td>
        </tr>
        <tr>
            <td>测试商品1</td>
            <td>100</td>
            <td>@Html.ActionLink("购买本产品", "Buy", "Home", new { productid = "001" }, null)</td>
        </tr>
        <tr>
            <td>测试商品2</td>
            <td>200</td>
            <td>@Html.ActionLink("购买本产品", "Buy", "Home", new { productid = "002" }, null)</td>
        </tr>
    </table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.2 购买方法的权限审核

    当2.1中的跳转到Home中的Buy方法时,系统会进行权限认证。Buy方法的代码如下:

    [Authorize]
    public ActionResult Buy(string productid)
    {
        return View();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    代码很简单,就是添加了一个特性。而这个特性的一个功能,就是MVC进行判断,若没有认证,则进行跳转到登录界面。其配置就是在项目的web.config中。

      <system.web>
        <authentication mode="Forms">
          <forms loginUrl="~/Account/LogOn" timeout="2880">
          </forms>
        </authentication>
      </system.web>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    而LogOn登录界面就是,上面的第二个图片。LogOn.cshtml的代码如下:

    @model AuthorizeDemo.Models.LogOnModel
    
    @{
        ViewBag.Title = "LogOn";
    }
    
    
    @using (Html.BeginForm())
    {
    <div>
        <fieldset>
            <legend>Account Information</legend>
    
            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.Password)
            </div>
    
            <div class="editor-label">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </div>
    
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    若详细看第二张图片(LogOn.cshtml)的URL,就会发现其URL是这样的:

    http://localhost/AuthorizeDemo/Account/LogOn?ReturnUrl=/AuthorizeDemo/Home/Buy?productid=1&productid=1

    即,在LogOn的后面自动添加了原来界面的URL(即ReturnUrl=/AuthorizeDemo/Home/Buy)以及相关参数。

    为什么会自动添加这个呢?查看MVC的源码就会发现,[Authorize]的处理原理如下:

    1、在AuthorizeAttribute中的OnAuthorization方法中的逻辑如下:

    
    //判断上下文中是否有用户的登录信息
    //若无登录信息后,进行进一步的处理
    IPrincipal user = httpContext.User;
    if (!user.Identity.IsAuthenticated)
    {
        return false;
    }
    
    //若结果为false,即用户没有登录信息,则将创建一个HttpUnauthorizedResult对象
    filterContext.Result = new HttpUnauthorizedResult();
    
    //HttpUnauthorizedResult就是一个401的变体。
    context.HttpContext.Response.StatusCode = StatusCode;
    if (StatusDescription != null)
    {
        context.HttpContext.Response.StatusDescription = StatusDescription;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2、当[Authorize]的抛出HttpUnauthorizedResult异常后,MVC中FormsAuthenticationModule类中的OnLeave方法,就会捕捉到这个异常。然后在这个方法的内部,具有重定向的功能。重定向就包含了两个功能:1、web.config中的登录界面配置。2、登录后的ReturnURL。

    因此刚才看到的LonOn的URL中包含了ReturnURL的内容。

    2.3 登录详细操作

    LogOn.cshtml界面,点击Log On登录按钮后,会已POST方式,进行提交到LogOn方法。方法的代码如下:

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
    
        //使用Membership进行创建用户
        MembershipCreateStatus createStatus;
        Membership.CreateUser(model.UserName, model.Password,"", "question", "answer", true, null, out createStatus);
    
    		//以上这部分的代码,应该放在注册方法中实现,这儿为了省事和验证,就统一放在LogOn方法中。
    		//这样就有个bug,每次登录都会创建一个用户。
    		//这儿只是为了演示使用,因此把注册的代码,合并待这儿了
    
    		//使用Membership的验证功能
        if (Membership.ValidateUser(model.UserName, model.Password))
        {
        	 //设置cookie
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
    		
    			//判断ReturnURL是否满足条件,若满足条件,则重定向到;否则,转到主页上
            if (	Url.IsLocalUrl(returnUrl) && 
            			returnUrl.Length > 1 && 
            			returnUrl.StartsWith("/")&& 
            			!returnUrl.StartsWith("//") && 
            			!returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
    
        return View(model);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    上面的代码中,使用了Membership进行创建用户、验证用户等操作。那问题来了,Membership怎么创建?把用户又保存到哪里了?怎么能够看到呢?

    2.4 Membership

    Membership是把用户信息保存到数据库了。是保存到SQL Server LocalDB数据库了。这个数据库是跟随VS安装,自动安装了。所以Membership直接把数据放到这儿。具体位置在哪儿呢?就在应用程序中的App_Data文件夹下,如下图所示:
    数据库
    怎么打开这个文件,看看里面的内容呢?可以通过SSMS中添加数据库进行查看
    查看的方法
    【注意】直接访问App_Data中的文件会遇到访问访问权限的问题。可参考解决问题的链接

    可通过相关的SQL查看数据库中的数据

    select * from dbo.aspnet_Membership
    
    select * from dbo.aspnet_Applications
    
    select * from dbo.aspnet_PersonalizationPerUser
    
    select * from dbo.aspnet_Profile
    
    select * from dbo.aspnet_Users
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.4.1 Membership

    Membership.CreateUser的源码如参考连接:CreateUser

    2.4.1 Membership改进(自定义数据库)

    Membership可以连接localDB,能连接其他数据库吗?答案可以的。可以通过相关参数设定,即可连接到其他的数据库中。具体如何进行,可参考自定义数据库

    其他的参考连接:自定义数据库

    3 参考连接

    1、使用Membership创建用户管理
    2、自定义数据库
    3、基于表单的身份验证【推荐
    4、ReturnURL中返回到其他站点的时候

  • 相关阅读:
    【计算机网络】数据链路层:使用广播信道的数据链路层(1)
    linux KVM的网络设置方法(bridge和nat)
    基于PSO粒子群算法的MPPT最大功率跟踪Simulink仿真,PSO采用S函数实现
    Java基础面试题
    Financial Statement Analysis with Large Language Models论文精读
    shell脚本之数组
    [Err] 1054 - Unknown column ‘xxx‘ in ‘where clause‘ 异常报错
    Java NIO Selector 的使用
    乱七八糟:程序员(媛)请保护好自己
    Exoplayer异常:4003, MediaCodecAudioRenderer error,format_supported=YES
  • 原文地址:https://blog.csdn.net/zlbcdn/article/details/127710387