gaoshikao
新手上路

UID 82076
精华
0
积分 25
帖子 20
金钱 25 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2006-10-24
状态 离线
|
php登陆验证之方案
每个步入php学习的人,我想最开始接触的东西就是用户的登陆验证以及状态更新了,我也一直在被这个问题困扰,难道就没有安全的人性化的解决办法嘛?
如果仅仅用cookie,则难以保证有效的安全;如果仅仅用session,难以保证用户的持久登陆,我觉得最持久最安全的办法是session+cookie+数据库。在这一方面,我对discuz的做法很佩服,我觉得它的验证是一个非常完美的解决方案。
先说下cookie的特点:存放在客户端,可以人为改变,不安全
再说下session的特点:关闭浏览器则退出登陆,持久性不好
那么discuz就是把三者有机的结合在一起,保证安全,准确,持久。在客户端存放sid,auth这两个信息。sid是sessionid的简写,其实就是表XX_sessioins的sid,auth是一个认证字符串,它是经过加过密的,只要authkey不被公布,能保证足够的安全性。客户端的这两个值都可以改变(因为是存放在cookie里的吗),但是只要不同时改变,那么就可以通过其中的一个而自动更新另一个,否则,如果都改变,那么就退出登陆了。在这个基础上,理解以下代码就非常容易了。
<?php if($sid) { if($discuz_uid) { $query = $db->query("SELECT s.sid, s.styleid, s.groupid='6' AS ipbanned, s.pageviews AS spageviews, s.lastolupdate, s.seccode, $membertablefields FROM {$tablepre}sessions s, {$tablepre}members m WHERE m.uid=s.uid AND s.sid='$sid' AND CONCAT_WS('.',s.ip1,s.ip2,s.ip3,s.ip4)='$onlineip' AND m.uid='$discuz_uid' AND m.password='$discuz_pw' AND m.secques='$discuz_secques'"); } else { $query = $db->query("SELECT sid, uid AS sessionuid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'"); } if($_DSESSION = $db->fetch_array($query)) { $sessionexists = 1; if(!empty($_DSESSION['sessionuid'])) { $query = $db->query("SELECT $membertablefields FROM {$tablepre}members m WHERE uid='$_DSESSION[sessionuid]'"); $_DSESSION = array_merge($_DSESSION, $db->fetch_array($query)); } } else { $query = $db->query("SELECT sid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'"); if($_DSESSION = $db->fetch_array($query)) { clearcookies(); $sessionexists = 1; } } }
if(!$sessionexists) { if($discuz_uid) { $query = $db->query("SELECT $membertablefields, m.styleid FROM {$tablepre}members m WHERE m.uid='$discuz_uid' AND m.password='$discuz_pw' AND m.secques='$discuz_secques'"); if(!($_DSESSION = $db->fetch_array($query))) { clearcookies(); } } if(ipbanned($onlineip)) $_DSESSION['ipbanned'] = 1;
$_DSESSION['sid'] = random(6); $_DSESSION['seccode'] = random(6, 1); } ?> 我在这里只给出构思,大家可以慢慢理解。那么discuz是如何做到更新用户状态的呢?是通过一个updatesession函数,这个函数在每次非ajax页面都是执行,入口是footer.htm的{eval updatesession();}
关于和登陆有关的其他设置,我就不详细说明了。
我的一点理解,若有纰漏,希望大家指正。
|
|