You should store the time of the last action / browsing of the user and the IP.
So you could verify over time that your session remains alive and only allow the access of who is logged in at that time and still inform if there is an attempt to login to another location, that the user is already connected to another computer and provide even the IP.
Example, if your session stays alive for 30 minutes, when the user enters the system, or navigates between the pages, does some action, you save the time in the database and the IP.
| Horario | Endereco de IP |
|------------------|------------------------|
| 2014-11-07 08:20 | 200.100.50.10 |
When you login or page change or any action on the system, you update this data, always obeying the session expiration time.
If IP of the new access = last access IP , access should be allowed as it is the same. Get the new schedule and update:
| Horario | Endereco de IP |
|------------------|------------------------|
| 2014-11-07 08:40 | 200.100.50.10 |
If it is new access IP than the last access IP , then check the times: new access time should be greater than the last access time + session lifetime .
Eg:
Novo Acesso Ultimo Acesso Tempo Vida Sessao
2014-11-07 08:55 2014-11-07 08:40 + 30
2014-11-07 08:55 2014-11-07 09:10
As 08:55 is earlier than 09:10 (considering the dates clear) it means that you have another active session and the user can not do any action, including login.
Let's assume now that he tried to access at 09:15
Novo Acesso Ultimo Acesso Tempo Vida Sessao
2014-11-07 09:15 2014-11-07 08:40 + 30
2014-11-07 09:15 2014-11-07 09:10
The new access was made after the expiration of the active session of the other user so he can login / do actions and the database is updated.
| Horario | Endereco de IP |
|------------------|------------------------|
| 2014-11-07 09:15 | 100.200.50.40 |
When the user logs out, these fields would be set to null
or, better than that for ease of comparison, to default where access was possible.
Ex. in case of logout:
| Horario | Endereco de IP |
|------------------|------------------------|
| null | null |
With default values (making comparison easier in any situation, avoiding exceptions in programming):
| Horario | Endereco de IP |
|------------------|------------------------|
| 2000-01-01 00:00 | 0.0.0.0 |
In case the logged in user loses the connection and his IP is modified he loses access and can only access again when his session expires, that is, in my example, 30 minutes. For this, the ideal is to evaluate the session time that will be used, making a balance between the time that the user needs to have between one action and another until the session expires and the time that the user can expect if this happens (IP change and need to wait for the session to expire). It is believed that short sessions are safer. You can apply 5 or 10 minutes to shorten this time and prevent the user from remaining logged in if you quit and do not log out.
To avoid this, you can use a key generated in the login step and store it in a cookie, replacing the IP ID with the generated key, thus circumventing this part of the IP. Remembering that cookies are editable, with some maneuvers it would be possible to access from more than one location. I prefer to approach using IP.
This is one of the ways to do this, in the various possible ways of implementation.