分享
 
 
 

一个完整、安全的用户登录系统

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

在使用PHP编程的时候,我有一个习惯,不太喜欢使用现成的库文件,例如PHPLib或者其它类似的库,在这个系统中,我也打算自己写一个库文件,它需要处理认证、确认email,更新帐号(密码,email)等事情。

为了在保证该系统安全的同时,不会加重我现有数据库的负担。因此这个新的系统要依赖cookies。这确实是一个两难的选择,因为如果只是设置一个用户名的cookie,是很不安全的,这行不通,但从数据库的负担考虑,我也不能加入一个简单的无序码而交由我的数据库来进行验证。

解决的方法是同时设置两个cookie,一个是用户名的cookie,一个是无序码的cookie。这个无序码实际上是由用户名和一个超级密码(只有程序设计者知道)组合通过md5()函数运算产生的。由于md5()是一个单向的无序码,因此是不可以破解的。在用户更改email时,我也可以用该email和超级密码产生一个无序码,以让用户确认修改。这实际上是一个公匙/私匙类的系统。不明白?不要紧,下面再慢慢说明。

有趣的是,这个系统的扩展能力是可以达到无穷的,因为该系统的主要工作是计算md5()函数的值,而且由web服务器完成,在负载增加时,可以加入其它的服务器来分担负载,虽然认证系统不会拖跨一个数据库,但是这样做就让最终的瓶颈只能出现在数据库上。

以下是该库中的两个函数--记号产生和记号认证函数。

<?php

$hidden_hash_var='your_secret_password_here';

$LOGGED_IN=false;

unset($LOGGED_IN);

function user_isloggedin() {

global $user_name,$id_hash,$hidden_hash_var,$LOGGED_IN;

file://已经进行无序码的检测了吗

file://如果是的话,返回该变量

if ( isset($LOGGED_IN) ) {

return $LOGGED_IN;

}

file://are both cookies present?

if ($user_name && $id_hash) {

/*

由cookies中得来的用户名和系统超级密码产生一个认证用的无序码如果该无序码与cookie中的无序码一样,则cookies中的变量是可信的,用户已经登录

*/

$hash=md5($user_name.$hidden_hash_var);

if ($hash == $id_hash) {

file://无序码符合,设置一个全局变量,这样我们在再次调用该函数的时候,

file://就无需再次进行md5()运算

$LOGGED_IN=true;

return true;

} else {

file://两个无序码不符合,没有登录

$LOGGED_IN=false;

return false;

}

} else {

$LOGGED_IN=false;

return false;

}

}

function user_set_tokens($user_name_in) {

/*

一旦用户名和密码通过验证,就调用这个函数

*/

global $hidden_hash_var,$user_name,$id_hash;

if (!$user_name_in) {

$feedback .= ' ERROR - User Name Missing When Setting Tokens ';

return false;

}

$user_name=strtolower($user_name_in);

file://使用用户名和超级密码创建一个无序码,作判断是否已经登录用

$id_hash= md5($user_name.$hidden_hash_var);

file://设置cookies的有效期为一个月,可设置为任何的值

setcookie('user_name',$user_name,(time()+2592000),'/','',0);

setcookie('id_hash',$id_hash,(time()+2592000),'/','',0);

}

?>

再来看另一段有趣的代码,用户怎样才能安全地改变他们的email地址呢?他们可以在任何时候改变email地址,但是要进行确认。

<?php

function user_change_email ($password1,$new_email,$user_name) {

global $feedback,$hidden_hash_var;

if (validate_email($new_email)) {

$hash=md5($new_email.$hidden_hash_var);

file://改变数据库中确认用的无序码值,但不改变email

file://发出一个带有新认证码的确认email

$user_name=strtolower($user_name);

$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) {

$feedback .= ' ERROR - Incorrect User Name Or Password ';

return false;

} else {

$feedback .= ' Confirmation Sent ';

user_send_confirm_email($new_email,$hash);

return true;

}

} else {

$feedback .= ' New Email Address Appears Invalid ';

return false;

}

}

function user_confirm($hash,$email) {

/*

用户点击认证email的相关连接时,连到一个确认的页面,该页面会调用这个函数,

*/

global $feedback,$hidden_hash_var;

file://verify that they didn't tamper with the email address

$new_hash=md5($email.$hidden_hash_var);

if ($new_hash && ($new_hash==$hash)) {

file://在数据库中找出这个记录

$sql="SELECT * FROM user WHERE confirm_hash='$hash'";

$result=db_query($sql);

if (!$result || db_numrows($result) < 1) {

$feedback .= ' ERROR - Hash Not Found ';

return false;

} else {

file://确认email,并且设置帐号为已经激活

$feedback .= ' User Account Updated - You Are Now Logged In ';

user_set_tokens(db_result($result,0,'user_name'));

$sql="UPDATE user SET email='$email',is_confirmed='1' WHERE confirm_hash='$hash'";

$result=db_query($sql);

return true;

}

} else {

$feedback .= ' HASH INVALID - UPDATE FAILED ';

return false;

}

}

function user_send_confirm_email($email,$hash) {

/*

这个函数在首次注册或者改变email地址时使用

*/

$message = "Thank You For Registering at Company.com".

"\nSimply follow this link to confirm your registration: ".

"\n\nhttp://www.company.com/account/confirm.php?hash=$hash&email=". urlencode($email). "\n\nOnce you confirm, you can use the services on PHPBuilder.";

mail ($email,'Registration Confirmation',$message,'From: noreply@company.com');

}

?>

评论:或许我们在用户认证方面不是采用这种方法,而是采用session等方式,不过这篇文章在如何进行加密和确认方面,还是对我们有所启发的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有