欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

使用PHPLIB进行Session的管理和认证(转载)

程序员文章站 2022-03-24 22:50:04
...

session

PHPLIB还可以做很多别的事情,例如数据库类。本篇文章只是对PHPLIB的简单介绍。有很多类和功能都没有提到。你可以到http://phplib.netuse.de去获取更多的帮助文档
---------------------------------------------------------------------
测试环境:标准环境

  首先要说明一个事实,用Web页面设计需要保存客户当前状态的程序时极为不便,例如在线Shopping,作为一名程序员,你必须时时面对在各个主页之间传递的状态参数。客户的身份认证、他已做出的选择、他当前的状态等等,Web主页并不会替你保存这些状态信息,你必须自己小心处理这些参数,这给我们带来了太多的不便,利用 http://url?var1=x1&var2=x2 来在主页间传送参数实在太危险,尤其是变量中包含用户注册信息时很容易被sniff,那么,我们如何解决这个问题呢?

  PHPLIB解决了这个问题,它是在PHP3上的一个扩展,提供了很多类库,使得程序员能很容易地建立一个交互式Web站点,PHPLIB最基本的功能包括用户认证,Session管理,权限及数据库的抽象化。

  安装PHPLIB前你必须在你的服务器上先安装好php3,PHPLIB可以运行在Cgi方式或apache附加模块方式。PHP3的版本必须时在3.0.5之上,PHP3早期版本可以在编译时使用参数 --enable-foce-cgi-redirect来获得支持,如果不这么做的话,会出现安全问题。PHP3的配置中 track_vars 需要设置为 enabled。同时需要一个数据库,PHPLIB支持MySQL、Oracle、ODBC、PostgreSQL、Sybase。

  第一步,PHPLIB的类库需要根据系统进行初始化,你可以修改local.inc文件,其中包含着一些基本参数,你可以根据自己机器的情况来进行修改。

  我们说明一下PHPLIB的工作原理,每一个使用PHPLIB的页面首先必须可以找到运行PHPLIB的必须类库文件,我们可以在php3.ini中设置auto_prepend变量来支持,PHPLIB分发包中包含一个prepend.php3文件,将auto_prepend指定为prepend.php3后,各页面就会自动包含PHPLIB类库,我们还可以将PHPLIB类库所在目录加进include变量中,以便可以找到这些文件,当然,最苯的办法就是指定绝对路径,这可不是个好主意!

第二步,每一个使用PHPLIB的页面中,你必须使用函数page_open进行初始化。这会告诉PHPLIB,你现在或将来会用到状态保存。一个典型的page_open例子包含到了认证、Session、权限:

page_open(array( "sess" => "Cms_Session", "auth" => "Cms_Auth", "perm" => "Cms_Perm"));
?>

  数组变量(sess,auth,perm)用来初始化一些状态保存对象,注意:必须使用PHPLIB内置名(sess,auth,perm),这些内置名是你在local.ini中所定义的,page_open函数必须在页面内容输出到浏览器之前被调用。(如果你将来不会用到认证的话,可以不初始化sess),php3脚本最后应以page_close()结束,这将会将有关状态数据写回到数据库中,如果你忘了的话,将会,哈哈哈。。。

  因为PHPLIB使用了Cookies来保存状态信息,所以page_open()函数必须在页面内容输出到浏览器之前被调用, 这里的页面内容可以是任何HTML信息或者空行,如果你发现了错误"Oops - SetCookie called after header has been sent",这表明在page_open()之前向浏览器输出了些什么,你要特别留意空行,因为非常难找到,典型的错误是在标记之间输出了空行,你应检查在local.inc和prepend.php3文件中是否包含了空行,这也是一个非常容易出错的地方。

  PHP使用了一种比基本认证方法更为复杂的架构,这使得安全有了更好的保证。

  举例来说,对于你想要限制访问的页面,会首先使用page_open来调用"auth" => "auth_class" ,初始化认证状态对象后,状态就会被保存起来,随后当客户再访问别的页面的时候,认证系统就会首先检测用户的身份是否已经经过认证。

  让我们解释一下,当一个用户第一次访问页面时,他的身份未经过认证,PHPLIB会调用一个注册窗口(并非在WINDOWS中的弹出窗口),你可以自己设计注册窗口的样式,当用户输入他的用户名与口令,并按下提交钮后,身份认证工作就开始了,随后的情况有些复杂,让我们慢慢解释……

  这里分两种情况,如果用户的浏览器不能兼容JavaScript的话,认证工作就象询问嫌疑犯一样,用户名与口令被送往服务器,与存放在那里的数据进行比较。如果用户的浏览器与JavaScript兼容,这就麻烦一些了,PHPLIB首先会在客户端的页面中放入一个用来加密的种子字串,名叫“challenge”,当用户提交该页面时,用户的用户名、口令和challenge字串会使用md5的加密方式进行加密,生成一个加密字串,将该加密字串与用户名提交给服务器。当服务器收到用户名和加密后的字串后,他根据数据库中的用户名与口令和得到的种子进行md5运算,将生成的字串与用户提交的字串进行比较,如果符合的话,说明用户身份是正确的,就允许用户进行随后的访问。这种方法的好处是:用户不用提交密码,这使得认证比较安全。

  Session 管理
  其实Session的管理和身份认证非常接近,当一个用户的身份认证过了后,随即用户的session就开始了,如果用户的浏览器支持cookie的话,将会建立一个session的id放入cookie,这个唯一的ID是由PHP3随机生成,然后又用随机种子
字串进行md5加密过了的,这里的cookie应该叫做session cookie,因为这个cookie是不会写到用户硬盘里去的,当一个session进行完的时候,该cookie也被完结了。如果用户浏览器不支持cookie的话,那么 该session的id将会放入url链中,因为是加密过的,所以窃取了也没用。session id存放着用户的有关信息,如用户已认证、认证到期时间、用户权限,和其他一些你可能需要的信息,方便我们取用。

  Session其实就是用户一次会话的过程。Session的管理并不是仅仅用来跟踪用户的注册,实际上,它还可以脱离认证来使用,你可以用它来存储任何你想要存贮的信息,这些信息可以在用户随后访问的页面中派上用场,当然前提是那些页面要使用PHPLIB。方法很简单,注册一个变量后即可在随后的页面中使用它,直至session结束。方法:

register( "variable_name"); ?>

  注意,这里的variable_name不是变量值,而是变量名,可以先指定变量名,随后再赋值。你在某个页面中可以改变变量的值,随后的页面访问该变量时会得到改变后的值。变量的类型是多样的,可以是一个字串,一个数字,一个数组,甚至一个对象。举例来说明:

$sess->register( "first");
if (check($firstname)) {
$first = $firstname;
}
?>

  注意:这里有一点很重要。你可以先注册一个变量随后再对它赋值,这样非常有效,我们大可以在脚本的任何地方定义变量而不赋值,而在随后的页面中再赋值,这样方便集中定义变量。大家可能注意到了,上面的例子中我们没有简单的对变量赋值,处于安全的考虑,你不应该轻率地将表单数据放入变量。上例中,我们对变量进行了检查,然后才对变量赋值。这是一个很好的习惯。大家应该注意。

  注册完一个变量,当页面最后调用page_close()函数后,各个session变量会被写回到数据库中,如果你忘记调用page_close()函数的话,变量就不会被写回数据库,将出现不可予知的后果。当变量被使用完毕后,你不在需要用到了,可以调用以下函数将变量删除:

$sess->unregister( "variable_name");
?>

  PHPLIB 7.0中,使用了一种存储结构,它允许你存储session数据到数据库中、共享内存中或者LDAP中。PHPLIB使用了数据库类,这使得你有了更多的选择。

  权限管理
  权限是和认证分不开的。当一个用户的身份被确认以后,你可以接着来确定他的级别及权限。当然,你必须先调用page_open来初始化"perm"对象。检查用户权限的命令如下:

$perm->check( "permission_level");
?>

  这条命令会检查用户是否符合你指定的级别,指定的级别应在local.inc文件中已经定义好,你可以自己定义各种级别。如果用户被检查出不符合级别。则perm_invalid()函数自动被调用。你可以建立自己的perm_invalid函数。

  以下是PHPLIB中检查权限的另一种方法:

$perm->have_perm( "permission_level");
?>

  have_perm与check函数不同,它只返回true或false,但并不退出脚本,这样我们可以更好的控制程序流程。

if ($perm->have_perm( "guest"))
{ //do something; }
elseif ($perm->have_perm( "admin"))
{ //do something else; }
else { //yet something else; }
?>