KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Keep users from logging in multiple times
PRODUCT: 4D Server | VERSION: 12.3 | PLATFORM: Mac & Win
Published On: November 23, 2011
Your current browser may not allow you to download the asset. We recommend Mozilla Firefox or Google Chrome.
Log In

This Tech Tip discusses a way to keep users from being able to login multiple times when connecting to 4D Server.

Three methods will be created:
1. isLoggedIn
2. trackUser
3. removeUser

Each of the three project methods must have the "Execute on Server" attribute enabled in the method properties.

isLoggedIn checks if the current user is already logged in. If the user is already logged in, the method returns True, otherwise False.

`Method: isLoggedIn
`Parameters:
`$1 - current username


C_TEXT($1;$userName)
C_BOOLEAN($0)
C_LONGINT($found_at)

If (Count parameters=1)
  $userName:=$1
  $found_at:=Find in array(<>usersLoggedIn;$userName)
  $0:=($found_at#-1)
End if


trackUser adds the current username to the interprocess array <>usersLoggedIn. This is done to keep track of all users logged in.
`Method: trackUser
`Parameters:
`$1 - current user

C_TEXT($1;$userName)

If (Count parameters=1)
  $userName:=$1
  APPEND TO ARRAY(<>usersLoggedIn;$userName)
End if


Once a user quits the application, they need to be removed from the array <>usersLoggedIn. This can be done using the method removeUser.
`Method: removeUser
`Parameters:
`$1 - current user


C_TEXT($1;$userName)

If (Count parameters=1)
  $userName:=$1
  $found_at:=Find in array(<>usersLoggedIn;$userName)
  If ($found_at#-1)
    DELETE FROM ARRAY(<>usersLoggedIn;$found_at)
  End if
End if


Initialize the interprocess variable, <>usersLoggedIn, inside the database method On Server Startup.
`Database Method: On Server Startup
ARRAY TEXT(<>usersLoggedIn;0)


isLoggedIn should be called in the database method On Startup. If the user is already logged in, quit the application, otherwise add the current user's username to the array <>usersLoggedIn by making a call to trackUser. Also, if the user is already logged in, <>userConflict is set to true to make sure the user is not removed in the database method On Exit.
`Database Method: On Startup
C_TEXT($user)
C_BOOLEAN(<>userConflict)
$user:=Current user

If (isLoggedIn ($user))
  <>userConflict:=True
  ALERT($user+" is already logged on!")
  QUIT 4D
Else
  trackUser ($user)
End if


When a user quits the application and <>userConflict is set to False, they need to be deleted from the array <>usersLoggedIn by calling the method removeUser.
`Database Method: On Exit
If (Not(<>userConflict))
  removeUser (Current user)
End if



Note: The above code does not handle unexpected log offs, such as a crash.

Commented by Randy Crawford on November 29, 2011 at 2:54 PM
Another possible solution to this is to create a record in a "User" table upon log in. This record stays loaded (and locked) the entire time the user is logged in. You can test the status of this record whenever a user logs in. If it is locked, you can deny access. If the user logs off or crashes out, this record is released and is available as soon as the user tries to log back in.