views:

239

answers:

2

Can you please suggest me a best method in PHP to make a user logs-in from only one machine at a time.

+4  A: 

You can't do this purely using session variables because logins from two separate machines will have separate sessions.

One solution is to have a database TIMESTAMP column called last_active_time. Set last_active_time to NULL when the user logs out.

If last_active_time is more than X minutes ago (where X is the timeout time), assume the user's session has timed out and allow the connection from the new location.

However, you will need to prevent the old session from becoming active again, either by implementing a timeout in the session variables, or add another column like login_session_id to the DB, and kick the user off if the session ID does not match the one in the DB.

Artelius
+2  A: 

Set a key in your session that you store in the database in the user table:

Table User

  • user_id
  • username
  • password
  • token

On Login:

  • create random token
  • UPDATE user SET token='MyRandomToken' WHERE username='username' and password='password';
  • $_SESSION['login_token'] = 'MyRandomToken';

On every page:

  • SELECT user_id, username, token FROM user WHERE token='$_SESSION['login_token']';
  • If not found then the logiin token is no longer valid.

This makes sure that a login expires automatically if there is a newer login. There can be only one logged in user per account at any time.

UPDATE

Just saw your comment to the Question. My answer does not work for you as it doesn't disallow a second login but instead invalidates any previous login.

If you want to prevent a second login then using a timestamp that you update on every page is the best solution:

On login:

(Assuming MySQL:)

SELECT user_id
FROM user
WHERE username='username'
AND password='password'
AND last_access < DATE_SUB(NOW(), INTERVAL 10 MINUTE);

If a row was found then the account exists and the login is not blocked by another login. You might want to split that into two queries (first check login, then check last access) to give a better error message for failed logins, otherwise it's either "account does not exist" or "blocked".

On every page:

UPDATE user
SET last_access=NOW()
WHERE user_id='CurrentUserId';
dbemerlin
-1 for including completely irrelevant MyRandomToken. All the OP needs to do is record the user id against the session id using a custom session handler - and check for an open session when the user logs in.
symcbean
@dbemerlin Thanks for your reply. Its a good solution for most of the websites and unfortunately not for me. Because, I'm working with a site which hosts lots of videos and live streaming of videos. So I won't be accessing the web server while I'm viewing videos. So last_access time won't get updated.
Joe
Depending on the type of streaming it is still possible to update the sessions. I.e. the Flash Media Server is able to ping a website in regular intervals while the stream is running. An even simpler solution would be to use AJAX to repeatedly ping the server from the browser. No Ajax call => user closed his browser.
dbemerlin