-
asp.net教程之ASP中简易用户访问控制
在站点的页面之间传递参数的通常方法是通过URL查询字符串,或者通过在表单中设置隐藏域的方法。另外的两种流行方法是使用cookie,或者使用ASP Session变量。在这篇文章里面,将讨论如何使用cookie和session变量来管理用户对站点页面的访问权限。
使用cookie来跟踪访问者
跟踪访问者访问页面的传统方法是使用cookies,cookie就是存储在用户一端计算机上的一个文本文件,当用户访问相应的域时,这些文件就被送到服务器上。做为基本应用,cookie被当作用户再次访问站点时验证和区分注册用户的手段,而不需要他们再次输入注册信息。同样,可以使用cookie保存用户上一次访问站点的一些设置。
在ASP中使用cookie非常简单,可以使用Request对象的Cookies集合取回所有保存在客户端的cookie数值,然后使用Response对象的Cookies集合创建或者修改cookie数值,并保存到客户端。
象ASP中许多对象一样,一个cookie不仅可以是集合中的一员,还可以自成为集合。创建一个单一cookie非常简单,代码如下:
Response.Cookies ("item-name") = "item-value"
创建一个包含多个数值的cookie,代码是:
Response.Cookies ("item-name")("sub-item-name") = "sub-item-value"
设置cookie的域属性、路径属性以及使用到期时间,相关代码是:
Response.Cookies ("item-name").domain = "domain-url"
Response.Cookies ("item-name").path = "virtual-path"
Response.Cookies ("item-name").expires = #date#
下面的例子在浏览器端创建了cookie选择,注意:必须在浏览器输出任何信息前创建cookie,因为它们是HTTP headers的一部分:
〈 %
Response.Cookies("SimpleCookie") = "SimpleExample"
Response.Cookies("CompoundCookie")("Value1") = "Value1" Response.Cookies("CompoundCookie")("Value2") = "Value2"
Response.Cookies("TimedCookie") = "TimedExample"
Response.Cookies("TimedCookie").path = "/" 'apply to our entire site Response.Cookies("TimedCookie").expires = #10/10/2005#
% 〉
〈 HTML 〉
〈 BODY 〉
...
〈 /BODY 〉
〈 /HTML 〉
读取cookies
通过使用request对象并遍历cookie集合,就可以读取所有cookie的全部内容。如果有些cookie含有多个数值,就通过遍历那个cookie自身集合来输出。
〈 HTML 〉
〈 HEAD 〉〈 TITLE 〉Reading the Cookie Collection〈 /TITLE 〉〈 /HEAD 〉
〈 BODY 〉
〈 B 〉The contents of your Cookies are:〈 /B 〉〈 P 〉
〈 TABLE CELLPADDING=0 CELLSPACING=0 〉
〈 %
For Each Item in Request.Cookies
If Request.Cookies(Item).HasKeys Then
'use another For...Each to iterate this collection
For Each ItemKey in Request.Cookies(Item)
Response.Write Item & "(" & ItemKey & ") = " _
& Request.Cookies(Item)(ItemKey) & "〈 BR 〉"
Next
Else
'print the complete cookie string as normal
Response.Write Item & "=" & Request.Cookies(Item) & "〈 BR 〉"
End If
Next
% 〉〈 /TABLE 〉
〈 /BODY 〉
〈 /HTML 〉
下图显示了执行上面代码的结果。但是,当你现在关闭浏览器并重新打开时,再运行这些代码,除了TimeCookie以为的所有数值都消失了。这是因为只有TimeCookie设置了“使用到期时间”,其他的当浏览器关闭时就自动消失了。
在cookie中保存登录信息
这里要讨论使用cookie保存登录信息的问题,并且看看在ASP页面间如何利用cookie数值。但是请记住:cookie仅仅被送往前次访问时所在路径相同的站点,也就是说cookie在初始设置时的环境中才能生效。如果没有设置cookie的path属性,它的数值默认就是当初创建时所在的虚拟路径。
这里有个例子描述保存登录信息到cookie中。由于没有设置“使用到期时间”,所以当前用户会话结束后cookie也就不存在了。
...
Response.Cookies("User")("v1") = "〈 % = Request("v1") % 〉" 'username Response.Cookies("User")("v2") = "〈 % = Request("v2") % 〉" 'password Response.Cookies("User").path = "/adminstuff" 'apply to admin pages
...
现在就可以在用户请求的每一个页面中寻找这个cookie了,如果没有找到,就重定向用户到登录页面:
...
If (Request.Cookies("User")("v1") 〈 〉 "alexhomer") _
Or (Request.Cookies("User")("v2") 〈 〉 "secret") Then
Response.Redirect "default.asp?nogood=yes&v1=" & Request.Cookies("User")("v1")
End If
...
使用ASP Session变量跟踪访问者
除了使用cookie,我们还可以充分利用ASP中的Session变量。我们可以在用户Session变量中保存数值,只要session变量还是激活的,这些保存的数值就可以被利用。通常,这些session变量将在用户最后一次请求页面后保持20分钟的时间,除非我们使用Session.Abandon方法明确地释放这些session变量。同时,可以使用ASP脚本中的Session.Timeout属性来设置这个过期时间。
使用session变量跟踪访问者要比使用cookie更安全,因为用户的session变量的内容不会随着页面请求而在网络上传递。除了初始登录以外,用户名与口令(或者任何数值)一直保存在服务器上。我们可以区别和认证访问者,将他们的登录信息保存在他们自己的Session对象中。当需要对访问者进行验证时,就从他们自己的Session对象中取会这些信息。举个例子,在用户登录后提交的页面中,加入如下代码:
...
Session("UserName") = Request("v1") 'username from logon dialog form
Session("Password") = Request("v2") 'password from logon dialog form
...
然后,当需要认证访问者时,就找到这些cookie并从中取回用户名和口令:
...
If (Session("UserName") 〈 〉 "alexhomer") _
Or (Session("Password") 〈 〉 "secret") Then
Response.Redirect "default.asp?nogood=yes&v1=" & Session("UserName")
End If
...
使用Session变量的问题
虽然Session变量是简单易用的,而且比其他方法要安全,但还是有一些问题。首先,只有访问者的浏览器支持cookie时,Session变量才能正常工作。尽管现在大多数浏览器都支持cookie,但是记住访问者可以拒绝使用它(这依赖于浏览器的安全设置)。
其次,特别在IIS4中,当浏览器请求多个页面时,Session变量可能被半途丢失。通常,遵循下面三个简单原则可以将这个漏洞减少到最小:
○ 只使用一个global.asa文件,放置在站点的根目录下。附带多个global.asa的嵌套应用程序,可能导致session变量使用越界。
○ 确认IUSE帐号或者它所属的组对global.asa文件至少有读的权限,并且IIS拥有Anonymous访问权限。
○ 要确认在所有页面中你都使用同样的字符大小写格式。Netscape(以及其他浏览器)对于/ThisFolder/ThisFile.asp 和 /thisfolder/thisfile.asp 这两个链接是当作在两个不同目录下的两个不同文件看待的。所以当从页面中取回一个cookie时,可能会因为大小写问题发生错误。
在数据库中保存登录信息
如果需要跟踪大量访问者的信息,仅仅使用include文件的方式就会变得很难管理。这时,我们可以使用数据库。利用此技术,同样适用于运行访问者加入或者在线登记的情况,并且将他们加入用户列表。对于这个问题在此不做进一步探讨。
使用数据库处理全部的过程是非常简单的!当用户提供了登录信息后,使用SQL的SELECT命令在数据库中查找输入的用户名,并取回匹配的口令。如果取回的口令与输入的口令一致,就允许他们进入下一步:
strSQL = "SELECT sPassword FROM Users " _ & "WHERE sUsername = '" & Request("v1") & "'"
加入登录信息的问题
然而,加入新用户是一个小难题。如果发现用户在数据库中不存在,并且决定使用ASP自动加入他们,我们就必须注意了。换言之,当用户填写新的信息时,可能有另外的用户使用同样的用户名在做同样的事情,而且后者动作快,首先在数据库中保存了信息,这样,前者的加入工作就不能完成。
有2个显然的方法可以避免这个现象。一个方法是:自动建立一个带空口令的新记录,用户日后可以修改它:
strSQL = "INSERT INTO Users (sUserName, sPassword) " _ & "VALUES('" & Request("v1") & "', null)"
一个更好的方法是:如果新记录创建成功,就使用一个过程返回一个特殊的数值(比如用户名),或者,如果不成功,返回错误信息。这样,用户就可以选择一个新的用户名。下面的例子是使用SQL Server存储过程,如果加入新记录成功,就返回用户名,如果用户名已经存在,就返回空字符串:
CREATE PROCEDURE AddUser @s_user varchar(12), @s_pword varchar (12) AS
IF EXISTS (SELECT * FROM Users WHERE sUserName = @s_user)
SELECT ''
ELSE
BEGIN
INSERT INTO Users (sUserName, sPassword)
VALUES(@s_user, @s_pword)
SELECT sUserName FROM Users WHERE sUsername = @s_user
END
这样就可以在ADO中执行这个过程,并检查返回值来确认是否添加成功。如果失败,就通知用户选择一个新用户名。这里有一些代码描述了如何使用上述的存储过程,你可以从本文下载的文件中找到这些代码。
以下是从表单中收集的数据:
strUserName = "NewUser1"
strPassword = "ThePassword"
定义数据库连接:
strConnect = "DRIVER={SQL Server};SERVER= yourserver ; " _
& "DATABASE= yourdatabase;UID= yourusername;PWD= yourpassword ;"
建立并打开数据库连接:
Set oCon = Server.CreateObject("ADODB.Connection")
oCon.Open strConnect
建立command对象,设置属性
Set oCmd = Server.CreateObject("ADODB.Command")
oCmd.ActiveConnection = oCon 'our open connection
oCmd.CommandType = 4 'it's a stored procedure
oCmd.CommandText = "AddUser" 'the procedure name
提供参数执行command对象,得到结果:
Set oRs = oCmd.Execute (lngRecsAffected, Array(strUserName,strPassword))
strResult = Trim(oRs.Fields(0)) 'ADO may add a space to the result
显示结果,如果错误,显示“user exists warning”:
If strResult = "" Then
Response.Write "User Already Exists"
Else
Response.Write "Added new user: 〈 B 〉" & strResult & "〈 /B 〉"
End If
% 〉
...
使用cookie来跟踪访问者
跟踪访问者访问页面的传统方法是使用cookies,cookie就是存储在用户一端计算机上的一个文本文件,当用户访问相应的域时,这些文件就被送到服务器上。做为基本应用,cookie被当作用户再次访问站点时验证和区分注册用户的手段,而不需要他们再次输入注册信息。同样,可以使用cookie保存用户上一次访问站点的一些设置。
在ASP中使用cookie非常简单,可以使用Request对象的Cookies集合取回所有保存在客户端的cookie数值,然后使用Response对象的Cookies集合创建或者修改cookie数值,并保存到客户端。
象ASP中许多对象一样,一个cookie不仅可以是集合中的一员,还可以自成为集合。创建一个单一cookie非常简单,代码如下:
Response.Cookies ("item-name") = "item-value"
创建一个包含多个数值的cookie,代码是:
Response.Cookies ("item-name")("sub-item-name") = "sub-item-value"
设置cookie的域属性、路径属性以及使用到期时间,相关代码是:
Response.Cookies ("item-name").domain = "domain-url"
Response.Cookies ("item-name").path = "virtual-path"
Response.Cookies ("item-name").expires = #date#
下面的例子在浏览器端创建了cookie选择,注意:必须在浏览器输出任何信息前创建cookie,因为它们是HTTP headers的一部分:
〈 %
Response.Cookies("SimpleCookie") = "SimpleExample"
Response.Cookies("CompoundCookie")("Value1") = "Value1" Response.Cookies("CompoundCookie")("Value2") = "Value2"
Response.Cookies("TimedCookie") = "TimedExample"
Response.Cookies("TimedCookie").path = "/" 'apply to our entire site Response.Cookies("TimedCookie").expires = #10/10/2005#
% 〉
〈 HTML 〉
〈 BODY 〉
...
〈 /BODY 〉
〈 /HTML 〉
读取cookies
通过使用request对象并遍历cookie集合,就可以读取所有cookie的全部内容。如果有些cookie含有多个数值,就通过遍历那个cookie自身集合来输出。
〈 HTML 〉
〈 HEAD 〉〈 TITLE 〉Reading the Cookie Collection〈 /TITLE 〉〈 /HEAD 〉
〈 BODY 〉
〈 B 〉The contents of your Cookies are:〈 /B 〉〈 P 〉
〈 TABLE CELLPADDING=0 CELLSPACING=0 〉
〈 %
For Each Item in Request.Cookies
If Request.Cookies(Item).HasKeys Then
'use another For...Each to iterate this collection
For Each ItemKey in Request.Cookies(Item)
Response.Write Item & "(" & ItemKey & ") = " _
& Request.Cookies(Item)(ItemKey) & "〈 BR 〉"
Next
Else
'print the complete cookie string as normal
Response.Write Item & "=" & Request.Cookies(Item) & "〈 BR 〉"
End If
Next
% 〉〈 /TABLE 〉
〈 /BODY 〉
〈 /HTML 〉
下图显示了执行上面代码的结果。但是,当你现在关闭浏览器并重新打开时,再运行这些代码,除了TimeCookie以为的所有数值都消失了。这是因为只有TimeCookie设置了“使用到期时间”,其他的当浏览器关闭时就自动消失了。
在cookie中保存登录信息
这里要讨论使用cookie保存登录信息的问题,并且看看在ASP页面间如何利用cookie数值。但是请记住:cookie仅仅被送往前次访问时所在路径相同的站点,也就是说cookie在初始设置时的环境中才能生效。如果没有设置cookie的path属性,它的数值默认就是当初创建时所在的虚拟路径。
这里有个例子描述保存登录信息到cookie中。由于没有设置“使用到期时间”,所以当前用户会话结束后cookie也就不存在了。
...
Response.Cookies("User")("v1") = "〈 % = Request("v1") % 〉" 'username Response.Cookies("User")("v2") = "〈 % = Request("v2") % 〉" 'password Response.Cookies("User").path = "/adminstuff" 'apply to admin pages
...
现在就可以在用户请求的每一个页面中寻找这个cookie了,如果没有找到,就重定向用户到登录页面:
...
If (Request.Cookies("User")("v1") 〈 〉 "alexhomer") _
Or (Request.Cookies("User")("v2") 〈 〉 "secret") Then
Response.Redirect "default.asp?nogood=yes&v1=" & Request.Cookies("User")("v1")
End If
...
使用ASP Session变量跟踪访问者
除了使用cookie,我们还可以充分利用ASP中的Session变量。我们可以在用户Session变量中保存数值,只要session变量还是激活的,这些保存的数值就可以被利用。通常,这些session变量将在用户最后一次请求页面后保持20分钟的时间,除非我们使用Session.Abandon方法明确地释放这些session变量。同时,可以使用ASP脚本中的Session.Timeout属性来设置这个过期时间。
使用session变量跟踪访问者要比使用cookie更安全,因为用户的session变量的内容不会随着页面请求而在网络上传递。除了初始登录以外,用户名与口令(或者任何数值)一直保存在服务器上。我们可以区别和认证访问者,将他们的登录信息保存在他们自己的Session对象中。当需要对访问者进行验证时,就从他们自己的Session对象中取会这些信息。举个例子,在用户登录后提交的页面中,加入如下代码:
...
Session("UserName") = Request("v1") 'username from logon dialog form
Session("Password") = Request("v2") 'password from logon dialog form
...
然后,当需要认证访问者时,就找到这些cookie并从中取回用户名和口令:
...
If (Session("UserName") 〈 〉 "alexhomer") _
Or (Session("Password") 〈 〉 "secret") Then
Response.Redirect "default.asp?nogood=yes&v1=" & Session("UserName")
End If
...
使用Session变量的问题
虽然Session变量是简单易用的,而且比其他方法要安全,但还是有一些问题。首先,只有访问者的浏览器支持cookie时,Session变量才能正常工作。尽管现在大多数浏览器都支持cookie,但是记住访问者可以拒绝使用它(这依赖于浏览器的安全设置)。
其次,特别在IIS4中,当浏览器请求多个页面时,Session变量可能被半途丢失。通常,遵循下面三个简单原则可以将这个漏洞减少到最小:
○ 只使用一个global.asa文件,放置在站点的根目录下。附带多个global.asa的嵌套应用程序,可能导致session变量使用越界。
○ 确认IUSE帐号或者它所属的组对global.asa文件至少有读的权限,并且IIS拥有Anonymous访问权限。
○ 要确认在所有页面中你都使用同样的字符大小写格式。Netscape(以及其他浏览器)对于/ThisFolder/ThisFile.asp 和 /thisfolder/thisfile.asp 这两个链接是当作在两个不同目录下的两个不同文件看待的。所以当从页面中取回一个cookie时,可能会因为大小写问题发生错误。
在数据库中保存登录信息
如果需要跟踪大量访问者的信息,仅仅使用include文件的方式就会变得很难管理。这时,我们可以使用数据库。利用此技术,同样适用于运行访问者加入或者在线登记的情况,并且将他们加入用户列表。对于这个问题在此不做进一步探讨。
使用数据库处理全部的过程是非常简单的!当用户提供了登录信息后,使用SQL的SELECT命令在数据库中查找输入的用户名,并取回匹配的口令。如果取回的口令与输入的口令一致,就允许他们进入下一步:
strSQL = "SELECT sPassword FROM Users " _ & "WHERE sUsername = '" & Request("v1") & "'"
加入登录信息的问题
然而,加入新用户是一个小难题。如果发现用户在数据库中不存在,并且决定使用ASP自动加入他们,我们就必须注意了。换言之,当用户填写新的信息时,可能有另外的用户使用同样的用户名在做同样的事情,而且后者动作快,首先在数据库中保存了信息,这样,前者的加入工作就不能完成。
有2个显然的方法可以避免这个现象。一个方法是:自动建立一个带空口令的新记录,用户日后可以修改它:
strSQL = "INSERT INTO Users (sUserName, sPassword) " _ & "VALUES('" & Request("v1") & "', null)"
一个更好的方法是:如果新记录创建成功,就使用一个过程返回一个特殊的数值(比如用户名),或者,如果不成功,返回错误信息。这样,用户就可以选择一个新的用户名。下面的例子是使用SQL Server存储过程,如果加入新记录成功,就返回用户名,如果用户名已经存在,就返回空字符串:
CREATE PROCEDURE AddUser @s_user varchar(12), @s_pword varchar (12) AS
IF EXISTS (SELECT * FROM Users WHERE sUserName = @s_user)
SELECT ''
ELSE
BEGIN
INSERT INTO Users (sUserName, sPassword)
VALUES(@s_user, @s_pword)
SELECT sUserName FROM Users WHERE sUsername = @s_user
END
这样就可以在ADO中执行这个过程,并检查返回值来确认是否添加成功。如果失败,就通知用户选择一个新用户名。这里有一些代码描述了如何使用上述的存储过程,你可以从本文下载的文件中找到这些代码。
以下是从表单中收集的数据:
strUserName = "NewUser1"
strPassword = "ThePassword"
定义数据库连接:
strConnect = "DRIVER={SQL Server};SERVER= yourserver ; " _
& "DATABASE= yourdatabase;UID= yourusername;PWD= yourpassword ;"
建立并打开数据库连接:
Set oCon = Server.CreateObject("ADODB.Connection")
oCon.Open strConnect
建立command对象,设置属性
Set oCmd = Server.CreateObject("ADODB.Command")
oCmd.ActiveConnection = oCon 'our open connection
oCmd.CommandType = 4 'it's a stored procedure
oCmd.CommandText = "AddUser" 'the procedure name
提供参数执行command对象,得到结果:
Set oRs = oCmd.Execute (lngRecsAffected, Array(strUserName,strPassword))
strResult = Trim(oRs.Fields(0)) 'ADO may add a space to the result
显示结果,如果错误,显示“user exists warning”:
If strResult = "" Then
Response.Write "User Already Exists"
Else
Response.Write "Added new user: 〈 B 〉" & strResult & "〈 /B 〉"
End If
% 〉
...
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式