How to sync the database and the session in codeigniter? - php

I got a problem, when the user is logged, and I assign the user their id, for example, 126. But when I doing maintain, or delete some banned user, for example, the user id 126 will remove from the database, but the user 126 still have the number 126 in his session. How can I 'delete' his session content when I detect my database have user id is deleted? Thank you.

Sounds to me like you are worried about ID 126 being blocked even if it gets assigned to a new user.
Shouldn't be a problem, cause IDs in those cases (usally) get created in an auto increment fashion and the DB (MySQL for sure, most others probably, too) chooses the next higher value to the highest ever generated value in such an auto-increment field.
So if the highes assigned value was 1234, then you can delete what you want, the next value is going to be 1235.
So your problem is not really a problem as it seems to me.

There are 2 solutions that I can think of this,
1.) Store the user credentials in the db,
every time the user makes an action you can check for credentials then kick the user out if already banned. I don't think its
2.) cache the logged in users, the cache should be global so the banned user's session can be checked

Related

User table in database is changed, how to update session?

Currently when the user logs in my site, a (PHP) session is started and his database row is saved in his $_session. I do so because the size of user's data is small for now, and this way I do not have to ask the database for user's data every time I need it.
The problem is that, when I want to add or change something during the development and I touch the database, the session is not updated this way. The user have to logout and login again to update the session. This is good for now since the site is in development phase, but in production this is not desirable.
I wouldn't delete session files, because people are lazy and I would avoid to force them to re-login every time something change in database, and I do not want to reload the session every X minutes. My solution for now is a boolean column inside the user's table, false by default, that I set true when I change the database. Every time a session is continued, session data will be updated if that value becomes true. Anyway this way I have to do a (small) query every time an user continues a session. I do not know if this will be a problem in production.
Is there an alternative / better way to solve my problem?
If I understand the problem correctly, one way to handle this would be every time a user row in the DB is updated that user's session data could be updated as well in PHP.
If it is not the user updating the records (such as an administrator changing a user's permissions) most likely you would want to force a logout of the user. If it is the user updating the records (such as changing information in their user profile) simply updating those values in the session variables may be enough.
In both of these cases you probably also want to provide a message to the user letting them know what happened.

Avoiding multiple logins to an account from different locations

I want to restrict multiple logins of the same user from different locations. How can I identify a user's multiple logins from different locations in the same/recent times? I think some flags and IP checking in a table might be a possible solution, but are there any better solutions?
Update:
I think the session or cookie might help if it for a single machine. Like when users log in for the first time create an activation key and store it, and every other time when users login to that machine, check the cookie value. likewise.
I would resolve something like that by making in user table, a activeKey column. Everytime user is logging in the activeKey is changed ( simple way subchar(md5(time().$username), 0, 16)), and and store it in session. Every time the webpage is refreshed/entered key would be checked. If dosn't match then logout with info. On correct logout key would be set to NULL, so when it could give a flag.
This metod could be combined with IP address, but only IP address could be cheated, same with MAC, and so on.
That is a main idea. There could be additional data like last login date, IP last login date, and so on.
You can have a table containing the IDs and the IP addresses of the users that are currently logged in. Just check against this table everytime someone logs in.
Here's a solution that doesn't require constant database access to work...
(which will avoid the requirement to check the session_id() against the database value every time you request/refresh a page, relieving db/server stress)...
1. On login, grab the pre-existing session_id stored in the DB for this user and do this:
session_id("the pre-existing session id in the database goes here");
session_start();
session_destroy();
2. Then start a new session and save this new session_id to the database, overwriting the previous one. This will logout the previous session on this user if there is one active (effectively logging out the other guy using this account).
Give it a try and let me know if that does the trick!!
NOTE: This is "in theory" as I haven't yet tried it. It's based on this accepted stackoverflow answer. And you should probably manually create the session_id based on something unique to each user, that way you don't wipe out a session that someone else is using that happened to be the same as the session last used by the user you are doing a check for.
I think, just have extra 2 columns for each user - "LastLoginTime" and "IPAddress" in your Users table. If the duration is too short and IPAddress vary then you can give a warning to the user. Additionally you can also inform the City & Country from which the user is logged in.
I would add in the users table an ipAddress column, a LastLogin date column, LogStatus column with boolean values (actually MySQL uses 1/0 for boolean) to check if the user is logged in or not, a Country column (although this could be bypassed by using proxy), and a blockedStatus column, again with 1/0 values, that would check if the user is blocked or not.
Then at log in page, you'd check if the user is logged in then he can't login, if he was recently logged in, and the country is different, then something is happening and you would need to block the account and send a email with a link to unblock the account if the legitimate user was the one logging in.

Questions about making 'if user is online' system

Please help start in the right way . I want to add 'if user is online' system. Which I will use to prevent multiple logins under 1 name, also this system will add option to users showing them who is online at the moment.
I understand that I need mysql table where I will store online users. But how can I understand each second if user is still here? if he logs out then ok, it's easy, but if he will restart? or something else ? So how can I controll all users and understand per second their status ?
UPDATE After some discussions with Cupcake I decided to have only who's online feature, letting 1 user to log in multiple times, cause it's difficult to prevent him from doing that in a comfortable way.
renew this table record each time user requests a page, updating access time field.
delete from this table all records which access time field is older than some reasonable timeout like 5 min
to prevent multiple logins under 1 name you have to store session id in the users table.
when user logins, stire current session id in this field
every time user requests a page, compare this id against actual session id, and make user relogin
What you could do, which is what I sometimes do, is this, in the user table have a column named session_hash or something similar.
And each time the user logs in, generate a new session hash yourself or use the session_id PHP has, as long as you use session_start on each page.
Then to retrieve the users row from the database, have a cookie with that session_hash.
Example
Login form
Username: [ ]
Password: [ ]
Remember?: [*]
[ Login ]
PHP page does the following
User logs in ->
System generates a session_id or "salt"
Updates the users row with the session_id or "salt" value
Check if the value of the "remember" checkbox is true ->
Sets a cookie with that session_id or "salt" with a month or so expiration date
Otherwise just create a normal cookie with the value
Then on each page do the following
Check if the session_id or "salt" cookie is set ->
If it is, fetch the users row from the database
SELECT * FROM users WHERE session_id/"salt" = value of cookie
What all this does if lets the user choose if they want to be remembered each visit, if they do create a cookie that doesn't expire for at least a month that way they will be remembered next time they come to the site, but if they login from another browser or computer the "salt" won't be valid on the other computer.
Simply invalidate all old sessions of the user, once he opens a new one. In that way, he can only run one session (aka one login) at a time.

How to secure this PHP form

I have a form for editing users. The user ID is passed to the client (in a hidden field) so that I know which user to update when the form is posted back to the server. My question is, how can I guard against users changing the ID in the DOM, thereby updating a record to which they should not have access?
The only ways I can think of are:
Save the user ID in the session. (Painful).
Run a salted hash on the user ID (and perhaps other form elements) and include it also as a hidden form element. (Not particularly secure?)
Are there other approaches?
Thanks!
EDIT: Hey, some great responses coming in. Note that the logged in user and the user being edited may be two different users, e.g. a Manager is editing a Staff record.
The best way to do this is to just check after submission if the user has the right to edit that user.
Don't pollute the session with this data, because it can get messy, for example when a user opens the same page multiple times.
It depends somewhat on the conditions under which the user is allowed to edit it.
At the heart of it, it comes down to:
Authenticate the user
Check if the user is authorized to make that change
Authenticating the user is usually a case of "Do the username and password match?" or "Is there an active session with a logged in user associated with it?"
Authorization depends on your business logic. It might be "Is the logged in user the same as the user being edited?" or "Does the user being edited have a manger field containing the id of the logged in user?" and so on.
In the first case, storing the user id in the session shouldn't be painful. In the second case, you just do a database lookup as one of the first things you do in the script.
Why are you relying on a hidden field for knowing which record to update? If the user is logged in you should already have the user_id of him with you on the session.
So you can just find which record to update by finding which user is logged in.
As mentioned, the fastest and painless way to sort this would be to stick the USER_ID in the session, period.
Comments saying that you "pollute" session with that information are plainly uneducated, ignore them.
The other thing I noticed in comments is the "check if the user has the rights to edit the entry" which implies there's some sort of hierarchical system in place, which seems not to be true.
Alternative to session storage would be, as you assumed already, obfuscating the USER_ID value in the hidden field somehow. You could either encrypt it, or instead of integer ID - you could use GUIDs but that has implications of its own, tho it makes it incredibly hard for someone to "guess" the correct GUID to mess around with the records.

Keeping track of users with PHP session id, cookie + database

I'm having a small bit of doubts here as to how sessions should be handled.
Right now, I have a MySQL database where the "users" table has a field for session_id. If NULL, the user is not logged in? If the value is the same as the value of the PHPSESSID cookie, than the user is logged in.
I don't know why, but I somehow feel this isn't good enough a way to make sure which user I'm dealing with. Is there something I'm missing, or do my fears hold no ground?
There's nothing essentially wrong with what you describe as far as I can see.
Of course, your login and logout mechanisms need to reliably add and remove the user ID when logging in or out. (insert a user name only when passwords match, etc) . Also, expired sessions need to be removed reliably. If that is given, this should be fine.
Just an extension on what Pekka said, you could also include a 'last seen' field into your table and use that as a judge because as Pekka mentioned about expired sessions, your database won't be informed that they are gone. So you will be forced to either make something so it manually checks the last time a user was there or something along those lines and then map that back to the session timeout (which I believe is either 15-30 minutes by default for PHP) and then after said amount of time, clear any of the users who haven't been active within the last X minutes.
A thought of the options above - tracking a user in the user table would only allow 1 session per user. I suggest storing the data in a table called sessions and have these columns:
sess_id | sess_userid | sess_ipv4 | sess_lastseen(datetime/timestamp) | sess_sessionid (varchar)
I believe that will allow user to have multiple logins, but with different session id's, even if they share the same public IP, allowing a laptop, tablet, phone etc - this way u can track each device separately from a single user.
hope this helps!
Another post ir read last week suggested having a prevsession and currsession and making sure u are assigning a new session (every 15 mins?) to the correct user. . swapping the sessions from old to new and storing the prev session as a check - not sure if this would help but thought id mention it.

Categories