8

I've been reading up on (mysql) triggers the last few days... specifically what I'm trying to do is figure out a good methodology for updating a user's information.


The case use for this is related to a user management system: Take for instance a admin user updating a regular user to a manager, this user type change would then enable|disable software features on the interface.

Problem: You won't know about this user type change unless you query the database and reset say for example the $_SESSION['user']['type'] variable, and or the user logs-in|out of the system.


Question: Is there any good methodologies to solve this headache?

Jordan Davis
  • 1,485
  • 7
  • 21
  • 40
  • might be helpful http://stackoverflow.com/questions/3426844/access-active-sessions-in-php – Jeff Puckett May 16 '16 at 18:37
  • php does its thing and then vanishes spitting out the HTML.I would run an unset or logout action for each UPDATE query of the user type. – Mihai May 16 '16 at 18:41
  • You need to add defined authorization using access control lists. For example an admin can elevate the role of any user while setting a group id and a parent id for this user in a db. And validate each page request using any changes in the group id or acl lists. Maybe i misunderstood your question.. Update: combine this with server side js or js to validate the group id. If for any reason js cannot connect, destroy all data objects. Or you could create a php function/extension that looks for any irregularities and acts accordingly, leaving the users to operate freely. – Nitin May 18 '16 at 20:36
  • 1
    You can write your own [session handler](http://php.net/manual/en/function.session-set-save-handler.php) which will store the session data in the DB. When changing users role or permissions also manipulate the related session (if exists). – Paul Spiegel May 21 '16 at 22:39
  • @PaulSpiegel yea I truly think that is the best method so far I've seen. – Jordan Davis May 22 '16 at 02:40

8 Answers8

4

I don't think mysql triggers would be ideal for this. Why? Because you will most probably end up with part of logic in php and part in mysql. It's a good thing to stay with one technology because it will be easier to maintain/debug code for you and your colleagues later.

So in your case, if you want the change of user role would take immediate action, you would have to either load user role on each script run or log out user using some flag in database that would signal that his session is not valid anymore (or you could implement your own session_set_save_handler that would save session somewhere in file where you could delete it to log out user).

It depends on your needs which solution would better fits your case.

  • If your roles logic is complicated and it consists of multiple roles assigned to one user as well as extra permissions assignments/excludes per user it may be better to do this check once on user log in and then just remember the result using session.
  • If checking for permissions on each script run isn't an issue, you can do it. But be aware, for security reasons, it may be a good practice to force user to log in again.
  • If the user log out could cause lose of work, you should let user log out itself and apply new permissions after next log in (you can show user a message that new permissions are awaiting log in to take effect).

So it really depends on your needs to choose if it's better to log out user, give him new permissions right away or wait until next log in.

Community
  • 1
  • 1
Buksy
  • 11,571
  • 9
  • 62
  • 69
  • @Medda86 yeah easiest solution.... What I also found which isn't entirely secure yet based on the browser type, is to use php to create a JavaScript constant. `` – Jordan Davis Mar 23 '17 at 00:21
2

Question: Is there any good methodologies to solve this headache?

Find good reasons not to do it!

While this might sound like a joke, i am completely serious. You have to consider:

  • What is the value of that feature?
  • Is it worth the headache cost?
  • What are the risks of that feature (incomplete work / system consistency)?
  • Do you have to change the system core?
  • Would you have to revalidate the system?
  • Are there other really great features (system improvements) waiting to be implemented?

Someone who doesn't feel comfortable answering these questions doesn't really need that feature.

Find simple alternatives:

  • Call the user and ask to log out.
  • Notify the user per email.
  • Provide a button for email notification.
  • Send email notification automatically after changing permissions.

This is no laziness. Just focus on real value.

Paul Spiegel
  • 30,925
  • 5
  • 44
  • 53
1

One alternative would be to do ajax requests, with some time interval, that will update your user $_SESSION. If you have any changes in your 'type', you can do whatever you want, like force user do re-login your application, or do nothing but update $_SESSION information. Of course, you need to know if you really need to get this information before user logout and login next time, with updated profile.

Felippe Duarte
  • 14,901
  • 2
  • 25
  • 29
1

I think storing your session into caching mechanism like Redis would give you added advantage. It is light weighted than storing session data in database. You can create clusters very easily. Click here to see sample implementation.

So once a user "type" changes, you can load the redis data cache and update it as per your wish.

Anik
  • 198
  • 2
  • 11
0

I think the safest way to do this, and the one that I would choose is the "headache" way.

  1. 'regular' user A logs in and opens session A1.
  2. 'admin' user upgrades A to a 'manager'.
  3. For now, session A1 is a valid session, but it will not grant the user 'manager' privileges.
  4. When user A logs out and logs back into session A2, this session will now grant the user all the privileges of a 'manager, having looked up the current 'type' from the database.

Alternative that may be slightly expensive depending on your application:

Every time a user presents a session token, use the database to check against the validity of the session. If that session has invalid info (ie. the 'type' no longer matches) then force the user to log back in again.


Adding another alternative:

Don't use a MYSQL trigger, when the application caller (the admin) updates User A's 'type', it also makes a call to wherever you're caching the sessions and either (a) updates the session (inadvisable*) or (b) renders the session invalid and forces the user to log in again.


*Note that all of these solutions require the user to re-enter their credentials after they have new-found 'manager' power before they have access to the 'manager stuff'. I think this is a safer practice than updating the session without any authentication.

Daniel Patrick
  • 3,980
  • 6
  • 29
  • 49
  • Yea very well aware of that technique, I feel like it isn't very good since it forces the user to log out where as the user might be doing something important... and or next time user logs in doesn't really give the application the powerfull look and feel of a live app – Jordan Davis May 16 '16 at 18:35
  • I think for security reasons, it's very reasonable to require the user to re-enter their credentials upon new-found manager power. – Daniel Patrick May 16 '16 at 18:39
  • Agree with the sentiment though. See my last alternative if you're not as concerned with that type of security. You could skip the mysql trigger and use the application mechanism that is "upgrading" the user to make a call and update the session cache. – Daniel Patrick May 16 '16 at 18:41
0

My recommended methodology would be to store the type of each user in the database. The problems that would arise if you decided to store the type as a session variable would be (among others):

  1. Once the session expires, this information would be lost. Usually sessions last 30 minutes, though you could modify this to be as long as you want. However if you create a session that lasts 1 month, then anyone who has access to that users computer would be logged into the users account without needing to use any password.

  2. You would be unable to use powerful and advances queries offered by databases (like MySQL for instance which uses SQL). If you store your information in sessions, sure you can find a way to look up each users information 1 by 1, but why reinvent the wheel? It is not easy developing a database structure from scratch, so I wouldn't recommend doing it.

Regarding your concerns on accessing a database once the information has been updated, I wouldn't say this information is as concerning as you might believe it to be. Lets imagine the following examples:

1)

If a user for instance is a manager currently and loads a website where he can do powerful actions, and right afterwards he is demoted to being a normal user, then having this information in the database would work perfectly. If the user tries to use his powers (that are no longer his), he would click a button that would send an a request to the database to confirm his type. Database queries are very fast, so speed is not an issue. I would be more concerned of the speed it takes for you to obtain information from a session variable than from the database.

2)

If the user was on a page while he was a normal user, and while on the page he became a manager, then he would be able to exercise his powers after refreshing the page. I mean if you used sessions and you wanted to have the page obtain the information automatically with something like AJAX and then update his options on the page, that would consume much more server power than a simple refresh.

To give a simple SELECT * FROM myTable WHERE id = 4 can take as little as 1 millisecond to be executed on a database. Databases have been especially designed for their speed which is why they are prefered

HOWEVER, maybe you don't have access to a database and that is why you are searching for an alternative? Well you are in luck! MySQLi is a database which only uses a file to store the information. It was especially designed for users that don't have much resources, and has many of the capabilities as MySQL would have.

Webeng
  • 7,050
  • 4
  • 31
  • 59
0

Since every user has a role or type it means that the ability of viewing or editing content in your application is solidly connected to this factor. This means that the 2 basic things that your session variables should have are userID and userType which you should also store in your database

These pieces of information can be passed to $_SESSION['user'] for example as a small array where your array key can be the userID and the userType the value.

$_SESSION['user']=array($userID => $userType);

Once a user login your initial values are stored to session. In order for your application to know what userA can view or edit in your application, you basically run a comparison in your script against the userType that userA has. But to achieve what you want you basically need to re-fetch the piece of information in the beginning of every VIEW/PAGE of your application. If new userType has been assigned to userA simply show a message that he/she will log out automatically in 15 seconds (give time to read the message itself) in order for the changes to take effect. While your user sees this message you take the current session data he/she may have and save it in database, since some session variables might be (or not) available in a upgrade or downgrade of userType. By placing the comparison of the userType in the beginning of each VIEW/PAGE of your application you save yourself of the headache that a user can loose data.

-1

If your scripts use $_SESSION['user']['type'] to know about the user's privileges, I would just change its value. Or perhaps I didn't understand the issue ?

Rosh Donniet
  • 418
  • 2
  • 10
  • Yea I don't think you understand it fully... to change it's value would mean every request I would have to check in the database table to see if `type` has change for the specific `user` then render the page based on the `type` of user ie. `admin|manager|employee`, I'm looking for a good methodology to manage and update `user-sessions` so there is no need to constantly check. – Jordan Davis May 12 '16 at 12:19
  • Well in that case I don't see any better way to do it. – Rosh Donniet May 12 '16 at 12:55
  • that very well might be the case will wait and see if anyone else has a few tricks. – Jordan Davis May 12 '16 at 12:58