如何防止在PHP网站中多次登录 [英] How to prevent multiple logins in PHP website

查看:66
本文介绍了如何防止在PHP网站中多次登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想防止在php应用程序中多次登录.

I want to prevent multiple logins in a php application.

首先,我在用户表中创建登录状态(活动,非活动).

First, I create login status (active, notactive) in a user table.

当用户A登录时,用户状态将设置为活动",如果用户注销,则状态将设置为非活动".当另一个客户端尝试使用相同的用户帐户登录时,我检查了用户表.如果用户仍处于活动状态,则错误登录将发送给用户.

When user A logs in the user status will be set to 'active', and if the user logs out the status will set to 'notactive'. When another client trys to login using the same user acount, I check the user table. If the user is still active the error login will be sent to the user.

发生问题,如果用户关闭浏览器,则可以更新用户表中的状态,因为用户没有单击注销.

The problem occurred, if the user closes the browser the status in user table can be update because the user didn't click logout.

您对此有何建议?

推荐答案

(请注意,尽管此处的技术仍然有效,但不应逐字复制PHP示例,因为存在合并用户的更安全方法-SQL查询中提供的值)

与其存储用户是否处于活动状态\非活动状态,不如存储一些可以按用户针对用户进行检查的属性;例如,每次用户尝试执行需要身份验证的操作时,都会检查该属性是否匹配,然后再进行操作.

Instead of storing whether the user is active\inactive, it is better to store some attribute which can be checked against the user on a per-action basis; as in, every time the user tries to do something which requires authentication, it will check to see that this attribute matches before it proceeds.

我建议您执行以下操作;

I recommend you do the following;

首先,创建一个哈希以在用户登录时唯一标识该用户.我可以想象 time() 的nofollow noreferrer> sha1 足以避免碰撞.无论您选择什么,请确保其变化足够大,以便另一个登录的用户接收相同哈希的机会极低(例如,请勿对IP地址或浏览器的用户代理进行哈希,因为这些不会变化)足够).

First, create a hash to uniquely identify the user whenever they log in. I'd imagine that a sha1 of time() would be enough to avoid collisions. Whatever you choose, make sure that it is varied enough so that another user logging in will have a incredibly low chance of receiving the same hash (for example, don't hash the IP address or browser's user-agent, as these are not varied enough).

第二,将此哈希存储在数据库中以及用户的会话中登录时.这样做会有效地注销"以前的用户,因为每次有人登录时哈希值都应该不同.

Second, store this hash in your database and in the user's session at the time of log in. Doing so will effectively 'log out' the previous user, as the hash should be different each time someone logs in.

由于我们正在使用会话,因此应将cookie自动放置在用户的浏览器中,该cookie将包含一个唯一ID,该ID可以根据用户的会话数据识别该用户. Cookie的内容并不是真正值得关注的.

Since we're using sessions, a cookie should be automatically placed in the user's browser which will contain a unique ID that identifies the user to his or her session data. The contents of the cookie are not really of concern.

接下来,创建一个名为authenticateUser()或类似功能的函数,该函数将在每个脚本的开头被调用以确保对用户进行身份验证.此脚本应查询数据库,以检查具有您用户ID的用户的哈希是否与您的哈希匹配.

Next, create a function called authenticateUser() or similar, which will be called at the start of every script to ensure the user is authenticated. This script should query the database, checking to see whether a user with your user's ID has a hash that matches your user's hash.

例如:

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()用户的IDhash(根据您的会话数据)和database link(对于数据库连接,您必须更早打开).

Then, we simply pass authenticateUser() the user's ID, hash (per your session data) and a database link (for a database connection you will have to have opened earlier).

如果authenticateUser()返回true,则表明用户已通过身份验证.如果为false,则表示该用户不是该用户,或者数据库不可用或存在SQL错误.

If authenticateUser() returns true, the user is authenticated. If false, the user is not OR the database is unavailable or there is an SQL error.

但是请注意,这将增加服务器负载,因为每个页面请求发送一次数据库请求.在大型项目上执行此操作可能不是那么明智,因为在任何时候都有成千上万的人正在登录.我确定有人可以提出改进建议.

Please note however that this will increase your server load as a database request is sent once per page request. It is probably not all that wise to do this on giant projects where thousands of people are logging in at any given time. I'm sure someone can suggest improvements.

此外,等待cookie过期并不是强迫不活动的人注销的最佳方法,因为您永远不要信任cookie.而是可以添加一个名为last_active的列,您可以在每次对用户进行身份验证时进行更新.这也将增加服务器负载,但是将允许您删除3小时不活动的用户使用hash来手动覆盖陈旧的登录.

Also, waiting for the cookie to expire is not the best way to force people who have been inactive to log out, as you should never trust cookies. Instead, you can add in an column called last_active which you can update every time the user is authenticated. This will also increase server load, but will allow you to manually override stale log-ins by removing the hash for users who were, say, inactive for 3 hours.

这篇关于如何防止在PHP网站中多次登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆