页:
[1]
| gaoshikao | 2008-2-19 03:29 AM |
|
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);
}
[/php]
我在这里只给出构思,大家可以慢慢理解。那么discuz是如何做到更新用户状态的呢?是通过一个updatesession函数,这个函数在每次非ajax页面都是执行,入口是footer.htm的{eval updatesession();}
关于和登陆有关的其他设置,我就不详细说明了。
我的一点理解,若有纰漏,希望大家指正。 |
| sanshi0815 | 2008-3-4 01:20 AM |
|
这个好是好,但是你既然用cookie了,那为什么不把用户名,id,还有其他需要的信息同时加密,保存.这样以后应用要简单的多!可以参考wind
这个模式如果你要扩展一个你的模块而使用dz的用户系统,那就比较麻烦了,因为我们不光是用uid,同时用户名,我们也需要,其他的,我们基本都不关心了,那个时候这个就麻烦了,别管操作什么样的表,只要是频繁,那自然就会有压力,但是就为了取个用户名,如此操作,那就比较累了 |
| gaoshikao | 2008-3-13 06:28 AM |
|
回复 #2 sanshi0815 的帖子
不是啊,discuz的加密字符串是加密uid,username的,通过sid和authkey就可以获取他们,如果想获取更多的信息,可以在sql语句里添加啊,而且我想如果真的需要更多的信息的话,提取一次也是值得的. |
Powered by Discuz! Archiver 6.1.0
© 2001-2006 Comsenz Inc.
Processed in 0.005862 second(s), 2 queries |