Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
641 views
in Technique[技术] by (71.8m points)

security - How to prevent multiple logins in PHP website

I want to prevent multiple logins in a php application.

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

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.

Do you have any suggestion about this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(Please note, that whilst the technique here is still somewhat valid; the PHP samples should not be copied verbatim as there are safer means of incorporating user-supplied values in a SQL query)


Instead of storing whether the user is activeinactive, 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;

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.

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.

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.

For example:

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;
    }
}

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).

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...