您现在的位置: 365建站网 > 365文章 > 8.8 用户模块

8.8 用户模块

文章来源:365jz.com     点击数:480    更新时间:2009-09-12 17:11   参与评论

由于在用户进行注册前,不能完成除浏览之外的任何操作,因此我们首先来讲解用户模块的制作。用户模块一般分为注册、登录、信息修改三个功能,另外,还可以有密码找回功能,本节将对这些功能依次进行讲解。

8.8.1 用户注册

在本案例中,打开页面regist.asp或者在网站页面的侧边栏点击“注册”并填写注册表单提交,都将打开页面regist.asp,实际上,侧边栏部分是将regist.asp页面中的表单提取出来放置的,因此我们主要来看regist.asp页面。

此页面通过GET方式请求,显示表单的部分,我们省去不谈,如果需要,你可以查看本书附送光盘中chapter7下的文件(由于篇幅原因,从本章开始,显示表单的HTML代码如无特殊,均省略)。当提交表单至本页面后,将进入如下处理:

'如果以POST方式发送数据到本页,则

If PostBack() Then

       '……省略变量定义

       '获取用户输入内容

       sEmail = Trim(Request.Form("reg_email"))

       sPassword = Trim(Request.Form("reg_password"))

       '使用正则验证用户输入合法性

       If doReTest(sEmail,"\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$") = False Then

       '注意这里我给出了另一种验证Email的正则表达式

              ShowError "您输入的Email格式可能有误!"

       End If

       If doReTest(sEmail,".{6,15}") = False Then

              ShowError "您输入的密码应该是6-15位!"

       End If

       '将用户密码使用MD5进行加密

       sPassword = MD5(sPassword)

       '判断该用户邮箱是否已经被注册     

       Set oRs = Server.CreateObject("ADODB.RecordSet")

      

       '在数据库中选取邮箱为用户填写邮箱的用户

       sql = "SELECT * FROM [ShareUser] WHERE UserEmail='" & sEmail & "'"

       oRs.Open sql,oConn,1,3

       '如果存在,说明已经被注册,则提示错误

       If oRs.RecordCount >0 Then

              oRs.Close

              Set oRs = Nothing

              oConn.Close

              Set oConn = Nothing

              ShowError "您输入的Email已经注册过了,如果忘记密码,您可以找回密码!"

       '否则进入注册

       Else

              oRs.AddNew()       '添加新记录

              '设定新纪录各字段的值

              oRs("UserEmail")          = sEmail

              oRs("UserPassword")    = sPassword

              oRs("UserAddTime")     = Now()

              '更新记录集

              oRs.Update

              '获得新注册的用户编号

              oRs.MoveLast

              lID = oRs("UserID")

              oRs.Close

              Set oRs = Nothing

              '为用户增加其默认的相册

              sql = "INSERT INTO [Album] (UserID,AlbumName) VALUES (" & lID & ",'默认相册')"

              '执行增加默认相册的SQL语句

              oConn.Execute sql

              Set oConn = Nothing

              '调用LoginSession过程并传入相应参数来处理登录

              LoginSession lID,sEmail,sPassword

              ShowSuccess "注册成功!"

       End If

       Response.End()

End If

在这段程序中,进行了如图8.9的处理:

图8.9

程序首先通过Request.Form集合获得用户填写的表单信息,而后使用自定义的正则表达式函数doReTest对其进行了正则测试,如果符合我们预设的正则表达式,则认为其是合法的,否则提示错误。

而后程序打开记录集,从数据库的ShareUser表中选取用户输入的Email的记录,如果记录集不为空,那么说明该Email已经被注册,此时提示错误,否则就使用oRs.AddNew方法加入一条新记录,而后通过oRs.MoveLast将记录集的指针移到末端,此时记录集指针对应的就是新加入的记录,我们读出此时的oRs("UserID")的值,即新加入的用户的编号,而后生成sql语句,为用户加入其默认的相册。最后完成注册操作。

8.8.2 使用MD5对用户密码进行加密

你应该注意到了在上面的源代码中,有这样一句,sPassword = MD5(sPassword),这里我使用MD5()这个自定义函数对用户输入的密码sPassword进行了处理,即,我使用MD5算法对用户密码进行了加密之后才放入数据库。

MD5的全称是Message-Digest Algorithm 5(信息-摘要算法第五版),它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。MD5算法是一种不可逆算法,即,我们使用MD5对密码原文进行加密,得到一个密码密文(无论原文如何,密文的长度总是固定的,一般来说,有32位和16位两种,其中16位是取32位密文的中间16位),而通过密文,无论我们如何运算,原则上都不能够得到密码的原文。

MD5的不可逆特性为我们的加密提供了方便,我们将用户的密码加密后存放在数据库当中,这样做的目的有二,第一,免除了网站管理员通过查看数据库,而得知用户密码的“嫌疑”,因为毕竟密码也算作一种隐私(很多人在所有网站注册用户,密码总是用相同的,这样一旦一个密码泄露,得知密码的人就可以登录其注册的所有网站了)。第二,即使黑客通过种种手段下载了网站的数据库,得知了数据库中保存的密码密文,由于不能够通过密文得到原文,他也无法从登录到网站上。

在实际的使用中,我们将用户输入的密码进行MD5加密,保存在数据库中,当用户登录时,我们再次将用户登录所输入的密码进行MD5加密,并与数据库中经过加密的字符串进行比对。以实现对用户密码的有效保存。

这里MD5加密的相关函数定义在include/lib/md5.asp中,如果有兴趣,你可以打开此文件,来学习其加密算法,如果没有兴趣,那么你可以在需要加密的时候,使用MD5()函数即可。

文本框: 扩展阅读:MD5真的安全吗?
很幸运的,我曾经是一名网络安全从业人员,因此也有机会在这里向你多介绍几句关于MD5的事情。在我上面的讲解中,提到通过密文,“原则上”不能够得到原文,这是由MD5的原理决定的—MD5是一种不可逆算法。然而,不可逆算法有两个大敌,就是穷举和密码库。穷举方法是这样的,黑客通过一个字典,这个字典内保存了人们常用的密码,它通过对字典中密码的MD5加密,得到密文,并与要破解的密文比照,如果相等,则可以得知密文对应的原文。而使用这种方法的破解时间,则是不可估计的,如果你对密码足够复杂,也许黑客几十年上百年都破解不出来。另外一种方法,密码库方法则几乎不需要任何时间,目前网络上有人搜集了大量密码所对应的MD5密文,并将其保存在数据库中,一一对应,黑客只需要访问相应网站,输入密文,就有可能查询出来其所对应的原文,这样的网站有http://www.xmd5.com和http://www.cmd5.com等。
所以说,MD5也不是百分百的安全,这也正应了安全业界的一句话:没有绝对的安全。

8.8.3 用户登录

用户登录是通过login.asp页面来完成的,这个页面获取用户输入的Email和密码,并在数据库中进行判断,该部分代码如下:

<%

If PostBack() Then

       Dim rs

       Dim sql

       Dim sEmail

       Dim sPassword

       '获取用户输入内容并进行合法性检验

       sEmail = Trim(Request.Form("login_email"))

       sPassword = Trim(Request.Form("login_password"))

       If doReTest(sEmail,"\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$") = False Then

              ShowError "您输入的Email格式可能有误!"

       End If

       If doReTest(sEmail,".{6,15}") = False Then

              ShowError "您输入的密码应该是6-15位!"

       End If

       '将密码使用MD5函数加密

       sPassword = MD5(sPassword)

       '建立记录集对象的实例rs

       Set rs = Server.CreateObject("ADODB.RecordSet")

      

       '取出相应用户名(邮箱)的记录

       sql = "SELECT * FROM [ShareUser] WHERE UserEmail='" & sEmail & "'"

       rs.Open sql,oConn,1,3

       '如果有记录,则说明用户存在

       If rs.RecordCount >0 Then

              '继续验证密码

              If rs("UserPassword") = sPassword Then

                     '如果密码的MD5密文和数据库中保存的密文相等,则处理登录

                     LoginSession rs("UserID"),sEmail,sPassword      '调用LoginSession过程

                     '关闭并清空记录集和数据库链接,以回收资源

                     rs.Close

                     Set rs = Nothing

                     oConn.Close

                     Set oConn = Nothing

                     '提示成功信息

                     ShowSuccess "登录成功!"

              Else

                     '关闭并清空记录集和数据库链接,以回收资源

                     rs.Close

                     Set rs = Nothing

                     oConn.Close

                     Set oConn = Nothing

                     '提示失败信息

                     ShowError "您输入的密码错误!"

              End If

       '否则说明用户不存在

       Else

              '关闭并清空记录集和数据库链接,以回收资源

              rs.Close

              Set rs = Nothing

              Set oConn = Nothing

              '提示成功信息

              ShowError "您输入的Email不存在!"

       End If

       Response.End()

End If

%>

用户登录过程我们已经多次涉及过了,这里的登录过程与前面的并无不同,因此我仅简单说一下。

程序首先从Request.Form集合中获取用户所填写的用户名和密码,而后和用户注册部分一样的,也适用正则测试的方法对用户输入的合法性进行了判断。而后程序打开记录集,从数据库的ShareUser表中选取相应Email的记录,而后进行判断,如果记录集为空,那么提示输入的Email不存在,否则再对用户输入的密码数据和数据库中的数据进行比对,如果相同,则调用自定义过程LoginSession将用户的登录信息保存在session中,否则提示错误。

8.8.4 用户密码找回——原理与实现

用户密码找回是用户模块中一个必要的部分,因为用户往往会由于自己忘记密码,或者帐户被盗,而导致需要找回密码。

通常来讲,用户密码找回有这样两种形式,第一种是用户在注册时填写一个密码提示问题和提示问题的答案,当用户忘记密码时,其可以在找回密码处输入用户名,网站给出其提示问题,要求填写提示问题的答案。而第二种则是网站根据用户在注册时填写的Email,向其电子邮箱中发送一封信件,在这个信件中指定了一个URL,这个URL中通过QueryString向网站传送一串随机字符串,作为密钥,用户打开此URL后即可更改密码。另外还有两种方式结合的方法,以提高安全性。在本案例中,主要采取第二种发送Email的方法。

这里的密钥原理是这样的,当用户在找回密码处输入用户名,而后程序生成一段随机字符串保存在数据库中,而后将此随机字符串发送到用户注册时填写的Email中,而后当用户打开邮件中的Url后,网站程序将其传递来的密钥与数据库中的进行比对,如果符合,就显示修改密码的表单。

所以,你可以很容易的发现到,这个功能需要两个页面来完成,本案例中,他们分别是getpassword.asp和findpass.asp。

首先我们来看生成密钥并发送的页面getpassword.asp,此页面当以GET方式请求时显示让用户填写其注册时邮箱的表单,当以POST方式请求时,进行如下处理:

<%

If PostBack() Then

       Dim oRs,sql,i

       Dim lUserID

       Dim sUserEmail

       Dim sPrivateKey

       '获取用户输入信息

       sUserEmail = Trim(Request.Form("UserEmail"))

       '取出用户记录

       Set oRs = Server.CreateObject("ADODB.RecordSet")

       sql = "SELECT * FROM [ShareUser] WHERE UserEmail = '" & sUserEmail & "'"

       '打开记录集

       oRs.Open sql,oConn,1,1

       '如果用户不存在

       If oRs.EOF AND oRs.BOF Then         '如果记录集为空

              '关闭和清空记录集和数据库链接

              oRs.Close

              Set oRs = Nothing

              oConn.Close

              Set oConn = Nothing

              '提示错误信息

              ShowError "您输入的Email还没有被注册呢!"

       '否则如果用户存在

       Else

              '获得用户编号以待后续使用

              lUserID = oRs("UserID")

              '及时关闭记录集和清空记录集变量

              oRs.Close

              Set oRs = Nothing

              '通过GenRadomString函数生成密钥

              sPrivateKey = GenRadomString(30)

              '向表FindPass加入一条修改密码请求

              sql = "INSERT INTO [FindPass] (UserID,PrivateKey,FindAddTime) VALUES (" & lUserID & ",'" & sPrivateKey & "',#" & Now() & "#)"

              '调用oConn对象的Execute方法执行SQL命令

              oConn.Execute sql

              '关闭和清空数据库链接

              oConn.Close

              Set oConn = Nothing

              '调用自定义函数SendMail向用户发送Email

              SendMail sUserEmail,"您在WeShare的密码找回信息","您好,请点击以下链接回到WeShare重置您的密码(请注意,密码尽在24小时内有效!):http://www.weshare.cn/findpass.asp?PK=" & sPrivateKey & ""

              '提示成功信息

              ShowSuccess "您的密码找回链接已经发送到您的Email:" & sUserEmail & "中..."

       End If

End If

%>

程序首先获得用户填写的表单中其邮箱地址,而后打开记录集,查询ShareUser表中相应的记录,如果记录集为空,则提示该Email还没有注册,否则先利用GenRadomString函数生成一个长度为30的随即字符串,而后生成INSERT指令的SQL命令并执行,以向密钥表FindPass中插入一条找回密码的记录。而后程序调用过程SendMail向用户的邮箱中发送信件。(注意在调试本页面的时候,请确保您在自己的计算机上已经安装了Jmail组件,如果没有安装,请参考第三章相应内容)

此时用户打开邮箱,会收到如图8.10的邮件:

图8.10

当用户打开此链接后,进入findpass.asp页面的处理,此页面源代码如下:

<%

Dim oRs,sql,i

Dim lUserID

Dim sUserEmail

Dim sPrivateKey

'获取用户修改密码密钥

sPrivateKey = Replace(Trim(Request("PK")),"'","''")

'根据密钥取出密码修改请求

Set oRs = Server.CreateObject("ADODB.RecordSet")

sql = "SELECT * FROM [FindPass] WHERE PrivateKey = '" & sPrivateKey & "' AND DateDiff('h',Now(),FindAddTime)<=24"

'打开记录集

oRs.Open sql,oConn,1,1

'如果请求不存在

If oRs.EOF AND oRs.BOF Then         '如果记录集为空,说明密码找回链接无效

       '关闭和清空记录集以及数据连接

       oRs.Close

       Set oRs = Nothing

       oConn.Close

       Set oConn = Nothing

       '提示错误

       ShowError "您的找回密码链接无效。"

Else

       lUserID = oRs("UserID")

       oRs.Close

End If

'如果是以POST方式请求页面,则说明此时进入了修改密码环节

If PostBack() Then

       Dim sNewPassword

       '获取用户输入的新密码

       sNewPassword = Trim(Request.Form("password"))

       '打开记录集,取出用户信息,以便修改

       sql = "SELECT * FROM [ShareUser] WHERE UserID=" & lUserID

       oRs.Open sql,oConn,1,3

       '如果帐户不存在

       If oRs.EOF AND oRs.BOF Then         '如果记录集为空

              '关闭记录集并提示错误信息

              oRs.Close

              Set oRs = Nothing

              oConn.Close

              Set oConn = Nothing

              ShowError "您的帐户已经不存在了!请联系管理员!"

       '如果帐户存在则修改其密码

       Else

              oRs("UserPassword")    = MD5(sNewPassword)

              oRs.Update

       End If

       oRs.Close

       Set oRs = Nothing

       '删除表FindPass中的找回密码请求

       sql = "DELETE FROM [FindPass] WHERE PrivateKey = '" & sPrivateKey & "'"

       '执行删除的SQL命令

       oConn.Execute sql

       '关闭和清空数据连接

       oConn.Close

       Set oConn = Nothing

       ShowSuccess "您的密码已经更新成功!请重新登录即可"

End If

%>

此页面将实现读取用户发送的密钥以及用户修改密码的两个操作,因此在页面的顶部,无论当前页请求方式是GET还是POST,都会进行判断其所输入的密钥是否存在的过程。这里获取用户传递来的密钥是通过Request集合,而并非Request.QueryString集合,这是因为当用户点击链接后,打开页面,如果密钥合法,则会在此页面显示一个表单,并以隐藏域保存密钥,以待发送表单至本页面时使用。

程序获取用户传递来的密钥,而后打开记录集,取出数据库中相应密钥对应的记录,如果不存在,则提示错误,如果存在,则读取出密钥对应的用户编号,保存在变量lUserID中。

而后如果当前页面是以Post方式请求,那么进入下面的修改密码的处理环节。

程序首先根据lUserID变量,打开ShareUser表中相应用户的记录,并将其UserPassword字段修改为用户提交的值,最后还需要执行SQL语句,删除FindPass表中相应的记录,以保证帐户安全。

8.8.5 用户资料修改

用户资料修改部分(account.asp)可以提供给用户一个修改其头像、昵称以及密码的部分,如图8.11所示。

图8.11

这里我首先谈一个特殊的地方,就是对密码的修改,你应当还记得,我们这个案例将用户的密码以不可逆加密形式保存在数据库中,因此在修改密码界面,我们不能显示出用户密码的信息了,因此这里我们使用了一个checkbox的HTML表单域,当选中此checkbox后,将要求用户输入原密码和新密码,以对密码进行修改,否则程序自动略过修改密码的部分。

如果在修改密码的地方不注意,则很可能出现问题,可能的问题有两种:第一,你选择在页面上的密码文本框中显示数据库中的信息,由于此时数据库中保存的是密码的MD5密文,你将其显示出来,在修改时肯定又将其加密一次(因为你不知道此时用户是否修改了密码,只能按照已经修了密码来操作),这样用户保存在数据库中的密文实际上是其密码原文经过两次MD5后的,这样他下次再登录时,就会提示密码错误;第二,你选择在页面上的密码文本框中显示空字符串,基于和上面所述一样的原因,你可能会将数据库中保存的密文修改为空字符串的MD5值,也会出现用户无法登录的情况。

来看此部分的代码:

<%

'因为只有登录后才能修改密码,因此先检测是否登录

If IsLogined = False Then

       ShowError "请登录!"

       Response.End()

End If

'……省略变量定义过程

'获取用户输入的值

lID = Trim(Session("weshare_UserID"))

sUserNickName     = Request.Form("UserNickName")

sUserHead            = Request.Form("UserHead")

sOldPassword        = Trim(Request.Form("OldPassword"))

sOldPassword        = MD5(sOldPassword)

sNewPassword      = Trim(Request.Form("NewPassword"))

sNewPassword      = MD5(sNewPassword)

'打开记录集取出当前用户记录

Set oRs = Server.CreateObject("ADODB.RecordSet")

sql = "SELECT * FROM [ShareUser] WHERE UserID=" & lID

oRs.Open sql,oConn,1,3

If oRs.RecordCount =0 Then       '如果用户不存在,则提示错误

       oRs.Close

       Set rs = Nothing

       oConn.Close

       Set oConn = Nothing

       ShowError "没有这个用户!"

Else '如果用户存在,则分为以POST方式或者以GET方式请求的不同来操作

       '如果提交表单则更新到数据库

       If PostBack() Then

              '设定数据库中信息为用户提交的信息

              oRs("UserNickName")   = sUserNickName

              oRs("UserHead")           = sUserHead

              '更新记录集

              oRs.Update

              '处理修改密码的过程

              If Trim(Request.Form("ChangePassword")) = "change" Then    '如果选中了checkbox(选择框)

                     If sOldPassword = oRs("UserPassword") Then          '如果旧密码输入正确

                            '更新密码

                            oRs("UserPassword")    = sNewPassword

                            LoginSession lID,oRs("UserEmail"),sNewPassword

                     Else                                                                       '如果旧密码输入错误

                            '提示旧密码错误

ShowError "您输入的旧密码错误!"

                     End If

              End If

              oRs.Update

              CloseDb()

              ShowSuccess "用户信息修改成功!"

       '否则从数据库中取出信息保存在临时变量中以待显示

       Else

              sUserNickName     = oRs("UserNickName")

              sUserHead             = oRs("UserHead")

              oRs.Close

              Set oRs = Nothing

       End If

End If

%>

在程序的开始部分,首先对用户是否登录进行了判断:如果用户没有登录,那么其自然不能修改密码。

而后程序从session变量集合中获取当前登录的用户的编号,并打开记录集从ShareUser表中取出当前用户的记录。

在取出完毕后,对当前页面的请求方式不同,进行了不同的分支。

如果当前页面是以POST方式请求,那么就获取表单内容,并更新在数据库当中,你需要特别注意这里对密码部分的处理,仅当Trim(Request.Form("ChangePassword")) = "change"时,才进入下面更新密码的部分。

如果当前页面是以GET方式请求,则将数据库中的相应信息保存在本地变量sUserNickName和sUserHead当中,以便下面的HTML表单使用。

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (480人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号