ASP.NET中登录功能的简单逻辑设计


                              概述

                              逻辑设计

                              1.接收参数

                              2.判断参数合法性

                              3.访问数据库

                              4.保存Session

                              5.保存Cookie

                              6.跳转到指定页面

概述


本文介绍的登录功能是一般登录逻辑,不能作为真正项目开发依据!!仅供学习参考!

由于登录功能涉及的知识点较广,这里只抽取部分主要知识点进行浅析,并没有作深入的探讨。

 

或许很多学.NET的初学者都接触过登录模块的设计:设计前台页面,输入帐号密码后登录,后台接收传过来的帐号密码,判断合法性,根据帐号密码在数据库中查找有没有实体,若有则登录成功;否则,登录失败

嗯,本文介绍的登录逻辑大体如此,但是仍有一些细微的地方让我们做得更好更完善,我希望你阅读此文后,学习到的不仅是登录功能,还有实际项目中我们要注意的地方

逻辑设计


先说一个例子:小明要去小红家(做作业呗,别想太多),他认识去小红家的路,小明和小红相互认识,拿着钥匙进屋而不被小红赶走。这就是一个登录过程,缺一不可

客户端(浏览器):获取用户输入的帐号(如:admin)、密码(如:123)

服务端:判断浏览器发送过来的帐号、密码是否与数据库中存在吻合的数据,执行如下图的逻辑:

                                    1.首先接收浏览器发送过来的帐号(如:admin)、密码(如:123)

                                    2.判断参数是否有非法字符、长度是否超出限制等。若非法,返回到登录页面(小明都不认识路,还做作业个屁啊)

                                    3.此时参数合法了,只是首要条件,它们还需要过数据库这一关。以帐号、密码作为查询条件,在数据库中是否有吻合的数据,若没有,返回登录页面(小明高兴地拿着钥匙进小红家,钥匙对不上或者小红不认识小明都进不了,慢着!小明怎么有小红家的钥匙。。)

                                    4.好吧,帐号密码都对了,登录成功!(他们愉快地一起做作业)(且慢!验证码呢?U盾呢?视网膜?DNA?…这里暂且不考虑0.0)

 

1. 接收参数 


一、服务器控件形式

     通过服务器控件,可以更加方便从后台代码获取对应的属性

     前台页面:

<form runat="server">
<asp:TextBox ID="txtUserName" runat="server" placeholder="用户名" title="用户名"></asp:TextBox>
<br/>
<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" placeholder="密码" title="密码"></asp:TextBox>
<br/>
<asp:Button ID="btnSubmit" runat="server" Text="登 录" OnClick="btnSubmit_Click"/>
</form>

    后台代码:   

protected void btnSubmit_Click(object sender, EventArgs e)
{
// 获取参数
string userName = txtUserName.Text.Trim(); //用户名,例如:"admin"
string userPwd = txtPassword.Text.Trim(); //密码,例如:"123"
}

     在服务器控件中会出现下面两种属性,请不要混淆:

    OnClientClick=“js_Click()”:表示客户端的点击事件,也就是点击的方法js_Click()是前台页面的js方法   

    OnClick=“btnSubmit_Click” :表示服务器端的点击事件,也就是点击的方法btnSubmit_Click是后台代码的事件的方法名,由于前台页面编译后会生成一个继承后台代码的页面类(涉及aspx生命周期,了解即可),所以方法不能用private修饰!否则无法访问此方法   

    知道他们区别之后我们就可以在事件中写获取参数的代码了

    string userName=txtUserName.Text.Trim();

    txtUserName必须跟服务器控件的ID名称相同!

    有时候用户在输入前、后喜欢敲几下空格,所以每一个严谨的程序员在接收参数的时候都会用Trim()来截断字符串左右包含的空格,这是很好的习惯。

二、普通HTML标签形式

     前台页面

<form method="post" action="/admin/login.aspx">
<input type="text" name="txtUserName" />
<br />
<input type="password" name="txtPassword" />
<br />
<input type="submit" value="登录" />
</form>

     当action不指定路径的时候默认提交到当前页面,注意上面例子的请求方式method="post",请求方式除了“post”之外还有“get”方式,但是登录一般采取post方式,因为如果采取get方式的话,帐号密码会填到url增加不安全性。

例如:../login.aspx?txtUserName=admin&txtPassword=123

     后台代码

protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod.ToLower() == "post")//当前请求方式为post
{
string userName2 = Request.Form["txtUserName"].Trim();
string userPwd2 = Request.Form["txtPassword"].Trim();
}
else if (Request.HttpMethod.ToLower()=="get")//当前请求方式为get
{
string userName2 = Request.QueryString["txtUserName"].Trim();
string userPwd2 = Request.QueryString["txtPassword"].Trim();
}
}

      对于两种请求方式,下面有几种获取参数的方法

 

 

 

2. 判断参数合法性 


判断参数的合法性,一般可以分为前台验证和后台验证

对于前台验证,我们可以通过一些js插件完成,或者通过增加服务器控件的一些属性来达到前台验证的目的,这里不作说明

对于后台验证,一般来说做非空验证即可

if (string.IsNullOrEmpty(userName)||string.IsNullOrEmpty(userPwd))
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "", " <script type='text/JavaScript'>alert('请输入用户名和密码') </script>");
return;
}

不推荐使用Response.Write()这种方式输出脚本

推荐使用Page.ClientScript.RegisterStartupScript(this.GetType(), "", " <script type='text/JavaScript'>alert('请输入用户名和密码') </script>");

3. 访问数据库


如果通过上面的验证,接下来我们就可以访问数据库了,这里只简单介绍相关的业务逻辑,对于不懂得访问数据库的同学建议自行了解ADO.NET。

对于简单练习的登录功能,我们可以直接在aspx.cs类中访问数据库

但是实际项目中为了降低模块间的耦合程度,我们建议使用“三层架构”。

 

 

 

接下来我们要在“业务逻辑层(Business Logical Layer)”也就是BLL层对帐号和密码做一些逻辑处理

MD5加密

          为什么采取md5加密?

         MD5算法具有以下特点:

         1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。

         2、容易计算:从原数据计算出MD5值很容易。

         3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

         4、弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

         5、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。     ---------来自百度百科

         数据库的用户表的密码一般是用明文密码(例如:“123”)通过md5加密成的md5值。

         所以我们要从数据库读取数据,一定要将明文密码转成md5值才能读取到数据

         虽说系统自带md5算法可以帮我们完成md5加密,但在实际操作中还要注意一个地方

         

           对于第一种方法是不推荐的,黑客可以用常用的明文密码经过md5加密的md5值与数据库中做对比,对比成功就知道明文密码了。

           这是由于md5生成的唯一性。例如:“123456”加密后就一定是“E10ADC3949BA59ABBE56E057F20F883E”

           所以一般项目工程都倾向第二种,通过“密钥”的干扰生成的md5值,即使黑客拿到这个md5值也不知道明文密码,只要他不知道这个“密钥”!

           下面是一个md5的加密方法:

/// <summary>
/// 加密数据 MD5
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt(string Text, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}

 

 

4. 保存Session


 

在介绍如何保存session之前,先区别缓存、session、cookie他们之间的关系,这可以帮助我们采用适当的保存数据的方式

Cookie:是存在于客户端浏览器的,存少量的数据,属于该浏览器的用户可以访问

Session:是存在于服务器进程中,可以存对象,数据量比cookie大,属于该进程的用户才可以访问

HttpContext.Current.Cache:是存在于服务器内存中,相当于内存,只要能访问该服务器的用户都可以从访问

            那么,可以根据你要分享数据的用户对象,和数据量的大小来采取适当的存储策略

篇幅有限,这里就不详细介绍session的原理。只说明要注意的地方:

Session[CNKeys.SESSION_ADMIN_INFO] = model;
Session.Timeout = 45;

 

1.Session保存的可以是对象,如果当前Session[CNKeys.SESSION_ADMIN_INFO]为null,就把model对象赋值上去,否则覆盖原来的这里的model对象是指从数据库成功读取的用户数据,包括用户帐号,md5密码,电话,邮箱等等,通过session保存用户对象,我们可以在程序中的任何一个网页通过Session[CNKeys.SESSION_ADMIN_INFO]读取用户的数据,而无需再访问数据库读取用户数据

2.Session默认保存是20分钟,如果这20分钟页面没有任何操作(例如:刷新),则自动销毁;如果有操作则顺延20分钟

3.Session[]中括号里面的是字符串,不建议用Session[“adminInfo”]这种方式,以后要使用的话工作量会加大,且增加出错机会(填错键值)

我们可以先定义一个类CNKeys,在类中定义常量字段SESSION_ADMIN_INFO

   

public class CNKeys
{
public const string SESSION_ADMIN_INFO="adminInfo";
}

这种方法,利用vs的智能提示可以方便且准确填写键值,以后要修改键名可以直接在类中修改,但是对于已经发布的网站需要重新编译程序,重新发布

当然你也可以用配置文件配置起来,以后要修改可以直接修改配置文件而无需重新编译程序

 

5. 保存Cookie


Cookie,它是存在于客户端浏览器的。由于浏览器自身可以随意获取,所以不建议保存敏感信息。它的保存方式也是键值对,只保存字符串,但不能保存对象。

HttpCookie cookie = new HttpCookie();
cookie.Name = model.user_name;
cookie.Value = model.user_name;
cookie.Expires = DateTime.Now.AddDays(3);//当前日期的3天后过期
Response.Cookies.Add(cookie);

为什么要设置cookie?类似于免登录3天,当用户成功登录后,把用户登录名保存到cookie,那么下次再打开浏览器的时候,浏览器就可以根据cookie值发送到服务器自动登录

6. 跳转到指定页面


Response.Redirect("index.aspx");

成功登录以后,我们就可以执行上面的代码,跳转到指定页面。

由于最近项目逼得挺紧的(加上年会活动排练囧!!),也很久没有写博客,于是选了“登录”这个题目练练手。毕竟自己还是有思路的

再参考别人的源码和结合自己的经验,这篇博文断断续续写了一个多星期,不容易

对于一些已经在工作的程序员来说,这种简单的登录功能的确很简单,所以比较适合初入ASP.NET的同学。。

欢迎批评点正。

ASP.NET中登录功能的简单逻辑设计的更多相关文章

  1. ASP.NET中登录时记住用户名和密码(附源码下载)--ASP.NET

    必需了解的:实例需要做的是Cookie对象的创建和对Cookie对象数据的读取,通过Response对象的Cookies属性创建Cookie,通过Request对象的Cookies可以读取Cookie ...

  2. ASP.net中导出Excel的简单方法介绍

    下面介绍一种ASP.net中导出Excel的简单方法 先上代码:前台代码如下(这是自己项目里面写的一点代码先贴出来吧) <div id="export" runat=&quo ...

  3. 浏览器中 F12 功能的简单介绍

    chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首 ...

  4. [转]chrome浏览器中 F12 功能的简单介绍

    本文转自:https://www.cnblogs.com/zhuzhubaoya/p/9758648.html chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己 ...

  5. 【F12】chrome浏览器中 F12 功能的简单介绍

    chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首 ...

  6. chrome浏览器中 F12 功能的简单介绍

    chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首 ...

  7. ASP.NET中一种超简单的Ajax解决方案

    为什么是Ajax2? 因为之前有一个blqw.Ajax,并且已经在项目中投入使用了,但是没有这个方便,这个是后来才弄的,为了纪念第一版的blqw.Ajax,所以这个就2了... 话说看了评论才发现,原 ...

  8. django登录功能(简单在POST请求)

    第一  先在templates中创立index.html !DOCTYPE html> <head> <meta charset="UTF-8"> & ...

  9. Asp.net 中高亮显示搜索关键字简单方法

    今天用到搜索时的高亮显示,百度了一下,如下面: 1.替换关键字,对字体变色.         public static string ReplaceRed(string strtitle, stri ...

随机推荐

  1. 洛谷P2344 奶牛抗议

    题目背景 Generic Cow Protests, 2011 Feb 题目描述 约翰家的N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为Ai,数字可正可负. ...

  2. array_uintersect、array_uintersect_assoc、array_uintersect_uassoc 的使用方法

    和 array_intersect 类似,只不过 array_uintersect* 系列函数的值比较使用自定义函数: 键的比较,array_uintersect.array_uintersect_a ...

  3. 题解【bzoj2038 [2009国家集训队]小Z的袜子(hose)】

    Description \(m\) 个询问,每次给出一个区间,求从这个区间中取出两个数使得它们同色的概率. \(n,m,a_i \leq 50000\) Solution 莫队模板题 最后的概率是 选 ...

  4. checkbox选择根据后台List数据进行回显

    需求:记住用户已经选择的 checkbox 选项,当用户再次对该 checkbox 进行选择操作时,应对该用户已经选择的 checkbox 选项进行选中操作. 示例代码: checkbox,js遍历后 ...

  5. 在使用Hibernate save()方法的时候 报错: org.hibernate.exception.ConstraintViolationException:could not perform addBath

    org.hibernate.exception.ConstraintViolationException:could not perform addBath 错误可能原因:实体属性的值与数据库字段类型 ...

  6. poi复杂excel的实现

    一:前言 最近帮一个朋友做excel的导出功能,对于我来说还是挺头疼,我看了下表格样式,对于我来说还是挺头疼的,想当年耗子刚刚出社会的时候做的第一份工作,第一份任务就是把把word转换为html,在这 ...

  7. word2vec 和 doc2vec 词向量表示

    Word2Vec 词向量的稠密表达形式(无标签语料库训练) Word2vec中要到两个重要的模型,CBOW连续词袋模型和Skip-gram模型.两个模型都包含三层:输入层,投影层,输出层. 1.Ski ...

  8. 用trigger触发datepicker

    jQuery UI的datepicker没有icon图片,工作需要,自己写了一个,原理是用div包裹住datepicker的input和一个button,隐藏掉input,而button被点击后也可以 ...

  9. .NET中的异常和异常处理

    .NET中的异常(Exception) .net中的中异常的父类是Exception,大多数异常一般继承自Exception. 可以通过编写一个继承自Exception的类的方式,自定义异常类! 异常 ...

  10. array_unique() 去重复

    array_unique() 定义和用法 array_unique() 函数移除数组中的重复的值,并返回结果数组. 当几个数组元素的值相等时,只保留第一个元素,其他的元素被删除. 返回的数组中键名不变 ...