This topic is locked
[SOLVED]

 Allow only one login per account (prevent user sharing)

8/21/2010 9:54:16 PM
PHPRunner General questions
F
FunkDaddy author

I am trying to implement a login solution that would only allow a user account to be logged-in to my application once (prevent multiple logins by sharing usernames and passwords).
I read posts on this forum (http://www.asprunner.com/forums/topic/10784-preventing-users-sharing-a-user-login/pagep37317hlsharingfromsearch1&#entry37317) that recommended I save the session_id value to the users table, then used that value to check against the logged in user. I understand the solution and was able to implement it, however, I am wondering if there is a way for me to include my code in only one event page that gets read by all pages, or do I have to manually add the same code to each page by using the "After Table Initialized" event.
I tried placing my code in the "After Application Initialized" but I get the following error:
Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in C:\wamp\www\iPhone_V3\include\dbconnection.php on line 34
Fatal error: in C:\wamp\www\iPhone_V3\include\dbconnection.php on line 36
However, I don't get this error when I used it in the "After Table Initialize". So there is obviously something related to "timing" of when that event kicks in (or so I think).
Anyhow, here is what I did:
In the "After Successful login" global event I added this:

-----



//Set the SessionID in the users_table

Global $conn;

$strUpdate = "

UPDATE

users_tbl

SET

Session_ID = '". session_id() . "'

WHERE

User_ID =" . $data["User_ID"];

CustomQuery($strUpdate);
$_SESSION["User_ID"] = $data["User_ID"];

$_SESSION["CurrentSession"] = session_id();



-----
Then in the "After Table Initialized" event for each table:

----



global $conn;

$sql = "SELECT * FROM users_tbl where User_ID=".$_SESSION["User_ID"];

$rs = db_query($sql,$conn);

$data = db_fetch_array($rs);
if ($data["Session_ID"] != session_id())

{

header("Location: login.php");

exit();

}

else

{return true;};



-----
This works... but I am looking for a way to include the "After Table Initialized" code in the "After Application Initialized" so I only have it written in one place (instead of in every table).
I tried a few things in the After Application Initialized event such as adding an IF statement to check whether there was a user logged-in by checking if the $_SESSION["User_ID"] was empty and to only run my code if it wasn't... but this did not work. I still got the error message as I showed to you in above in this email.
Thanks in advance for giving me some guidance on how to accomplish the goal of only allowing one user account to be logged in at a time (meaning, not allowing account info to be shared).
Cheers,

A
ann 8/23/2010

Marcelo,
you need to use Before loginevent on theEvents tab to check the logged in user. Here is a sample:

global $conn;

$sql = "SELECT * FROM users_tbl where FieldName='".$username."'";

$rstmp = db_query($sql,$conn);

$datatmp = db_fetch_array($rstmp);
if ($datatmp ["Session_ID"] != session_id()){

header("Location: login.php");

exit();

}

else{

return true;

}
F
FunkDaddy author 8/23/2010

Thanks for the reply Ann, however the solution you proposed has a few shortcomings for what I am trying to accomplish.

  1. Per you code, once a user logs-in successfully, then later on when they logout they would never be able to login to the application ever again. If you think about it, the SESSION ID would be saved to their user record and unless I delete that SESSION_ID from the users table, they would not be able to login since the next time they visit their session would have been assigned a different id (therefore not matching what was in the users table).
  2. I want to be able to pull a user "kill switch" (deactivate any user, at any given time). Meaning that I could "deactivate" them from the system immediately by simply changing their session_id info in their user record (this would kick them out of the application as soon as they visited any page). This is preferred instead of the traditional "active =1" or "active = 0" approach.... because the active approach requires the user to logout and/or session expire to prevent them from logging in again. My solution must be able to kick some off the application the moment they attempt to navigate away from whichever page they are currently visiting.
    I hope I was able to better explain what I am really trying to accomplish via this "kill switch" approach. The code I sent to you in the email works perfectly, the only issue is that I was hoping to avoid having to place it in every "after table initialized" event of each table. Instead, I was hoping for a more universal solution that let me write the code once and have it run on each page.. the problem is that the "after application initialized" throws error messages when I tried placing my code there (whereas the after table initialized event did not throw any errors even when using the exact same code).
    Thanks in advance. I look forward to your insights and suggestion on how I can accomplish my "kill switch" functionality with less code.

A
ann 8/24/2010

Marcelo,
As workaround you can add new date field and save current timestamp in this field in the After successful loginevent. Then check this timestamp and allow to login with the same login after 1 hour for example.
Also admin can change field where session_id is store manually and remove this value if needed.

F
FunkDaddy author 8/25/2010

Thanks for your help Ann.
For everyone, in case you are interested in this topic you can view a TIP & TRICK post I created here: http://www.asprunner.com/forums/topic/15072-tip-how-to-autologin-rolling-login-license-solution/