HI, I am doing ERP solution in C#(2.0) windows application and SQL2005 Database.The network application communicate through Database.I used normal technique for user login and logout, keeping a status bit.My problem is that when my application interrupted with any other reason user status might not change.That will cause the user can't login at next time.How can I solve this problem? Could you give any new technique for user manipulation?
How about keeping track of user logins by maintaining a session for each login? The quick-and-dirty solution is to then offer an option to have them login from a "new location" and invalidate the old session. Then when you go to perform an operation, first check if the session is still valid.
The better implementation is to keep the session alive and specify a timeout. (i.e. if the session is x-minutes old, invalidate it.) Then you won't see "phantom logins" from old orphaned connections - they automatically expire.
There are two common answers here:
- if you try to log in, and are already logged in, offer to break (reset) the existing login
- use a polling/timeout - i.e. have the app call a method every 2 minutes (for example) that updates a "last heard from"; if you haven't heard from somebody in 5 minutes (for example), then clear the flag
Why limit the number of times a user can login? In Windows it is common to start multiple instances of an application.
I must admit, I my Windows App there is also a part only one user is allowed. To see if other users are connected I use something like the polling algorithm from Marc. With an option to force the entry.
An update of the lock record once every minute, or two minutes is not that resource intensive (unless you have thousands of users).
If your intention is to disallow sharing of one username on different computers, after logging with valid password, log the unique token on that computer to staff.last_logged_at = @unique_token. On logout, set staff.last_logged_at = ''. This way even if the computer was interrupted(program crash due to virus, or accidentally pressed the reset button of the computer, etc, hence last_logged_at was not reset to '') the user can still logged in, just check if the token of the computer the user is currently logging in is same with last_logged_at. If it is the same, he/she can still logged on.
If some user tried to login using the username of other user, just check if the machine token of some user's computer is the same with the other user's last_logged_at, if it is not equal, disallow logging in, it means two users share the same password.
Now the scenario if the computer crashes really hard (processor melts, hard disk crash, OS needs reinstalling, etc). User must be allowed to use other computers. Make an administrative module that can reset the last_logged_at of the user.
For @unique_token, just use anything that is unique and permanent on a computer, let's say MAC address, or hash anything on OS settings.
pseudo code:
Logging In:
if (select count(*) from staff where staff_name = @staff_name and password = 'correct' and (last_logged_at = '' or last_logged_at = @unique_token) ) <> 0 then then
-- allow login
update staff set last_logged_at = @unique_token where staff_name = @staff_name
else if (select count(*) from staff where staff_name = @staff_name and password = 'correct' and last_logged_at <> @unique_token) <> 0 then then
-- disallow login
throw exception "You cannot use the same user name on two or more computers. Contact the administrator if you have any concerns"
else
-- disallow login
throw exception "Wrong password"
end if
Logging Out:
update staff set last_logged_at = '' where staff_name = @staff_name