Hello All,
Recently I have done some soul searching on the best way to
allow for complex user permissions on a web site while keeping
server resources in mind. I am hoping that some of you will have
some ideas or suggestions on the best way to implement a system
like this using CF. First a little background:
In my CF application I assign user accounts to a permission
group so different users can access different pages. For example, I
can assign user 'Joe Bob' to the 'Administrators' group which can
access pretty much everything, whereas the user 'Jane Smith' has
been assigned to the 'Contributors' group and can only access
certain pages.
Initially I assigned the permissions based on the name of the
permissions group, so when the user logged on I created a session
variable called AccountType which would contain the value,
"Administrator", "Contributor", etc. That way, my templates could
run a simple cfif to check if the person could see a particular
resource,link,etc.
However, now I am expanding the permissions scheme to allow
site administrators to create their own user groups with their own
unique names and permissions settings. The user account types are
stored in a database and each separate permission is stored as a
yes/no variable in a column. For example:
UserTypeID......Name
..............CanLogIn........CanAccessProducts......CanAccessBlog.......etc...
-----------------------------------------------------------------------------------------------------------------------------------------
1
...................Administrator.....yes................yes...............................yes
2 ...................Contributor
.........yes...............no................................yes
3....................Store
Manager.....yes...............yes..............................no
So the problem arises: How should these permission settings
be applied for the logged in users? I want to be conscious of both
server memory as well processing/requests to the DB and ease of
coding. Here are some ideas that I had:
IDEA 1: When the user logs on, do just as I was doing and
assign a session variable named UserType that stores the
UserTypeID. Then, within application.cfm, check if the user is
logged on, if yes, query the database (cached query) and get the
permission values for that account type and store them in a
structure which can be referenced as needed in that request.
Pros: In this method, the work appears to mostly be done by
the processor, db server. Since queries can be cached, I can use
the same cached query for multiple users that log into the site so
more than one user can share the cached query.
Cons: I think that reading a cached query and then building a
structure containing the values of the table on ever page load
might be overkill and might demand unneeded processing.
IDEA 2. This method is similar to #1 in that a session
variable named UserType will be created when the user logs on.
However the main difference is that the database won't be queried
for a permission column until it is actually needed. So if the user
tries to access page xyz.cfm, coldfusion checks the appropriate
column in the table based on the UserType variable and either
allows the user to see it or not.
Pros: This could potentially save some server memory if there
are a lot of users logged on at once and a lot of permission
columns in the database.
Cons: This could be a coding nightmare and will add a lot
more lines of code on many templates since pretty much every
template will make at least one permissions check.
IDEA 3: Another method which might work would be when a user
logs on, query the appropriate permissions records and store all of
the yes/no columns as a structure in the session scope. On each
page load (application.cfm), copy the structure stored in the
session scope which contains all of the permissions to the local
variable scope so it can be easily accessed by the page.
Pros: Using this method, I only have to query the permissions
once, and then access all the variables I need because they will be
stored in memory.
Cons: In the event that there are a LOT of permission
variables (assuming 100 or so) this could cause each logged in user
session to hold a lot of variables. I'm not sure how much server
memory a structure containing 100 values is, but I want to keep
that in mind so I don't hog too many resources unnecessarily.
What are your thoughts on this topic? Do you have any
suggestions or ideas for handling this type of situation?