一个完整、安全的用户登录系统
2008-03-13 03:39:32来源: 阅读 ()
在使用PHP编程的时候,我有一个习惯,不太喜欢使用现成的库文件,例如PHPLib或者其它类似的库,在这个系统中,我也打算自己写一个库文件,它需要处理认证、确认email,更新帐号(密码,email)等事情。 Chinaz^com
为了在保证该系统安全的同时,不会加重我现有数据库的负担。因此这个新的系统要依赖cookies。这确实是一个两难的选择,因为如果只是设置一个用户名的cookie,是很不安全的,这行不通,但从数据库的负担考虑,我也不能加入一个简单的无序码而交由我的数据库来进行验证。
解决的方法是同时设置两个cookie,一个是用户名的cookie,一个是无序码的cookie。这个无序码实际上是由用户名和一个超级密码(只有程序设计者知道)组合通过md5()函数运算产生的。由于md5()是一个单向的无序码,因此是不可以破解的。在用户更改email时,我也可以用该email和超级密码产生一个无序码,以让用户确认修改。这实际上是一个公匙/私匙类的系统。不明白?不要紧,下面再慢慢说明。
Www~Chinaz~com
有趣的是,这个系统的扩展能力是可以达到无穷的,因为该系统的主要工作是计算md5()函数的值,而且由web服务器完成,在负载增加时,可以加入其它的服务器来分担负载,虽然认证系统不会拖跨一个数据库,但是这样做就让最终的瓶颈只能出现在数据库上。 Chinaz.com
以下是该库中的两个函数--记号产生和记号认证函数。 中国站长.站
以下为引用的内容: <?php Chinaz $hidden_hash_var='your_secret_password_here'; Chinaz~com
$LOGGED_IN=false; function user_isloggedin() { 站.长站
file://如果是的话,返回该变量 站长.站
if ( isset($LOGGED_IN) ) { Www^Chinaz^com return $LOGGED_IN; 中.国站长站 } Chinaz@com file://are both cookies present? Chinaz^com if ($user_name && $id_hash) { 中.国.站长站 /* Chinaz_com |
由cookies中得来的用户名和系统超级密码产生一个认证用的无序码如果该无序码与cookie中的无序码一样,则cookies中的变量是可信的,用户已经登录。 站.长.站
以下为引用的内容: */ 站.长.站
$hash=md5($user_name.$hidden_hash_var); Chinaz@com if ($hash == $id_hash) { Www_Chinaz_com
file://无序码符合,设置一个全局变量,这样我们在再次调用该函数的时候, 中.国.站.长.站
file://就无需再次进行md5()运算 Chinaz_com
$LOGGED_IN=true; Chinaz@com
return true; Www_Chinaz_com } else { Www.Chinaz.com
file://两个无序码不符合,没有登录 Chinaz_com $LOGGED_IN=false; 中国站长_站,为中文网站提供动力
return false; 中国.站.长站
} 中国站长.站 } else { Www.Chinaz.com
$LOGGED_IN=false; Chinaz
return false; 中国.站.长站
} Www_Chinaz_com } Chinaz.com function user_set_tokens($user_name_in) { Www.Chinaz.com
/* Www_Chinaz_com
|
Www^Chinaz^com
一旦用户名和密码通过验证,就调用这个函数
Www_Chinaz_com
以下为引用的内容: */ 中国.站长站 global $hidden_hash_var,$user_name,$id_hash; 站.长.站 if (!$user_name_in) { 中.国.站.长.站 $feedback .= ' ERROR - User Name Missing When Setting Tokens '; 中.国.站长站 return false; Chinaz.com
} Chinaz^com
$user_name=strtolower($user_name_in); 中国站.长.站 file://使用用户名和超级密码创建一个无序码,作判断是否已经登录用 站长.站
$id_hash= md5($user_name.$hidden_hash_var); 中国.站.长站
file://设置cookies的有效期为一个月,可设置为任何的值 Www^Chinaz^com
setcookie('user_name',$user_name,(time()+2592000),'/','',0); Www@Chinaz@com setcookie('id_hash',$id_hash,(time()+2592000),'/','',0); 中.国站长站
} 中国站长.站 ?> 站.长.站
|
站长.站
再来看另一段有趣的代码,用户怎样才能安全地改变他们的email地址呢?他们可以在任何时候改变email地址,但是要进行确认。
Chinaz~com
以下为引用的内容: <?php Chinaz~com function user_change_email ($password1,$new_email,$user_name) { Chinaz@com global $feedback,$hidden_hash_var; 中.国站长站
if (validate_email($new_email)) { 中.国.站长站 $hash=md5($new_email.$hidden_hash_var); Chinaz~com file://改变数据库中确认用的无序码值,但不改变email Chinaz.com file://发出一个带有新认证码的确认email Www~Chinaz~com $user_name=strtolower($user_name); Chinaz@com
$password1=strtolower($password1); 站长.站 $sql="UPDATE user SET confirm_hash='$hash' WHERE user_name='$user_name' AND password='". md5($password1) ."'"; [中国站长站] $result=db_query($sql); 站.长.站
if (!$result || db_affected_rows($result) < 1) { Www.Chinaz.com $feedback .= ' ERROR - Incorrect User Name Or Password '; Chinaz
return false; Www~Chinaz~com
} else { Www@Chinaz@com
$feedback .= ' Confirmation Sent '; [中国站长站] user_send_confirm_email($new_email,$hash); Chinaz~com
return true; 中国站长.站
} Chinaz.com } else { 中.国站长站 $feedback .= ' New Email Address Appears Invalid '; Www_Chinaz_com
return false; [中国站长站]
} 中.国.站.长.站
} 中.国.站.长.站
function user_confirm($hash,$email) { Www@Chinaz@com /* Chinaz~com |
中.国.站长站
用户点击认证email的相关连接时,连到一个确认的页面,该页面会调用这个函数
Chinaz.com
以下为引用的内容: */ 中.国.站.长.站
global $feedback,$hidden_hash_var; Www@Chinaz@com file://verify that they didn't tamper with the email address 中国.站.长站
$new_hash=md5($email.$hidden_hash_var); 中国站长.站 if ($new_hash && ($new_hash==$hash)) { Chinaz
file://在数据库中找出这个记录 中国.站.长站 $sql="SELECT * FROM user WHERE confirm_hash='$hash'"; Www@Chinaz@com
$result=db_query($sql); Chinaz@com if (!$result || db_numrows($result) < 1) { Chinaz.com $feedback .= ' ERROR - Hash Not Found '; Chinaz_com return false; 中.国站长站
} else { Chinaz^com
file://确认email,并且设置帐号为已经激活 [中国站长站] $feedback .= ' User Account Updated - You Are Now Logged In '; Www.Chinaz.com user_set_tokens(db_result($result,0,'user_name')); Www.Chinaz.com
$sql="UPDATE user SET email='$email',is_confirmed='1' WHERE confirm_hash='$hash'"; 中国.站.长站 $result=db_query($sql); [中国站长站] return true; Chinaz.com
} 中国站.长站 } else { 中国.站长站 $feedback .= ' HASH INVALID - UPDATE FAILED '; 中国站长.站
return false; Www~Chinaz~com } 中.国.站.长.站 } 中国站.长.站
function user_send_confirm_email($email,$hash) { Chinaz~com /* 中.国.站长站 |
中.国.站.长.站
这个函数在首次注册或者改变email地址时使用 站.长站
以下为引用的内容: */ Www.Chinaz.com
$message = "Thank You For Registering at Company.com". Chinaz_com "\nSimply follow this link to confirm your registration: ". } [中国站长站]
?> Chinaz~com |
评论:或许我们在用户认证方面不是采用这种方法,而是采用session等方式,不过这篇文章在如何进行加密和确认方面,还是对我们有所启发的。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:有效防御PHP木马攻击的技巧
下一篇:面向搜索引擎的URL优化
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash