(请注意,尽管此处的技术仍然有些有效;但是不应逐字复制PHP示例,因为有更安全的方法将用户提供的值合并到SQL查询中)
与其存储用户是否处于活动状态非活动状态,不如存储一些可以按用户针对用户进行检查的属性;例如,每次用户尝试执行需要身份验证的操作时,它都会检查该属性是否匹配,然后再进行操作。
我建议您执行以下操作;
首先,创建一个哈希值以在用户每次登录时唯一标识该用户。我想,一个
sha1of
time()足以避免冲突。无论选择什么,请确保其变化足够大,以便另一个登录的用户接收到相同哈希的可能性极低(例如,请勿对IP地址或浏览器的用户代理进行哈希,因为这些不会变化)足够)。
第二,在登录时将此哈希存储在数据库中以及用户会话中。这样做将有效地“注销”先前的用户,因为每次有人登录时哈希都应不同。
由于我们使用的是会话,因此应将cookie自动放置在用户的浏览器中,该cookie将包含一个唯一ID,该ID可以根据用户的会话数据识别该用户。cookie的内容并不是真正值得关注的。
接下来,创建一个称为
authenticateUser()或类似函数,将在每个脚本的开头调用该函数以确保对用户进行身份验证。该脚本应查询数据库,以检查具有您用户ID的用户的哈希是否与您的哈希匹配。
例如:
function authenticateUser($id, $hash, $databaselink) { # SQL $sql = 'SELECt EXISTS( SELECT 1 FROM `tbl_users` WHERe `id` = ''.mysql_real_escape_string($id).'' AND `hash` = ''.mysql_real_escape_string($hash).'' LIMIT 1);'; # Run Query if ($query = mysql_query($sql, $databaselink)) { # Get the first row of the results # Assuming 'id' is your primary key, there # should only ever be one row anyway. $result = mysql_fetch_row($query); # Casting to boolean isn't strictly necessary here # its included to indicate the mysql result should # only ever been 1 or 0. return (bool)($result[0]); } else { # Query error :( return false; }}然后,我们只需传递
authenticateUser()用户的
ID,
hash(根据您的会话数据)和
databaselink(对于数据库连接,您必须先打开)。
如果
authenticateUser()返回
true,则对用户进行身份验证。如果为
false,则用户不是,或者数据库不可用或存在SQL错误。
但是请注意,这将增加服务器负载,因为每个页面请求发送一次数据库请求。在大型项目上执行此操作可能不是那么明智,因为在任何时候都有成千上万的人正在登录。我确定有人可以提出改进建议。
另外,等待cookie过期并不是强迫不活动的人注销的最佳方法,因为您永远不要信任cookie。相反,您可以添加一个称为的列,您可以在
last_active每次对用户进行身份验证时进行更新。这也将增加服务器负载,但是将允许您删除
hash3小时不活动的用户的,从而手动覆盖陈旧的登录。



