Question

I am writing an application which includes a number of dialog/modal divs that allow users to perform a variety of tasks e.g. upload image, send email etc.

My application has role-based security so when you are logged in it checks your session variables to find out who you are and then offers up the appropriate features.

At the moment I have all my dialogs/modals within the page that requires them. This means that if I want to use the same dialog box elsewhere in my website, I have to copy the code and put it on that page. This immediately made me think that I should:

  1. Create a .cfm file for each dialog box e.g. imageupload.cfm and emailsend.cfm
  2. Include these .cfm files using <cfinclude> on which ever page wants to use them

This potential solution causes me challenges because the page which will include the dialog boxes has many if/else statements to work out what to present to which user depending on their role (stored in a session variable).

So do I have to:

  1. Duplicate the if/else logical statements to the dialog box pages as well because the content served from imageupload.cfm for example will be different depending on your role
  2. Every page in the site is protected by the invoking a user-security.cfc file that checks that the user is logged in. Do I also have to make this call in every dialog box .cfm page? If I do this then there will be two invokes to the same user-security.cfc file within the same page because the dialog box page is being included in the main page. But if I don't invoke user-security.cfc from within the dialog box .cfm as well, then could someone go directly to those pages and start causing chaos?

Apologies that this is not a pure programming question and more theoretical best practice, but I'm not sure how to tackle it while keeping it scalable. I am using ColdFusion 10 on IIS 7.5

Était-ce utile?

La solution

You can increase your code reuseability as follows.

Create an application scope variable with an instance of your user-security.cfc file. Do this in the onApplicationStart() method of your Application.cfc file. Something like this:

application.SecurityChecker = CreateObject("component", "user-security");

Also in your onApplicationStart() method, create a list of pages that do not require a sercurity check.

application.SecurityNotNeededPages="page1.cfm,page2.cfm,etc";

Use these variables in your onRequestStart() method.

var ThisPage = listlast(cgi.PATH_INFO, "/");
if (ListFindNoCase(application.SecurityNotNeededPages, ThisPage) is false) {
application.SecurityChecker.CheckSecurityMethod(argumentcollection = session);
etc

This will solve the problem of people browsing directly to included pages if they are not logged in. It will also make your application run faster because you only have to create an instance of the user-security.cfc once, and it will be available for every user on every page request.

Edit starts here

In the comments, Adam Cameron says, "Also, onRequestStart() already receives the name of the file being requested as an argument; there's no need to use the CGI scope to get it, I think". That was news to me so I thought I'd check it out.

I ran a page that had this function.

<cffunction name="onRequestStart" access="public" returntype="boolean">
<cfdump var="#arguments#">
<cfreturn true>
</cffunction>

That gave me a key of 1, and value showing the path to the page I actually ran. So, doing things in the wrong order, I read the docs. Following those guidelines, I added this to the code above:

<cfargument name="targetPage" required="yes">

Not surprisingly, the dump gave a key of TARGETPAGE with the same value. Then I changed the name of the argument to "fred". The dump gave me a key of FRED with the same value.

The bottom line is, whether you use the argument sent to the page, or the cgi scope, you'll still have to use ListLast to get the name of the page.

Autres conseils

Create an index.cfm page basically consisting of a big switch statement. Your URLs are action.subaction ie index.cfm?action=email.send. Parse that in the index.cfm. Then for each case, check the security rules and cfinclude as needed. But yeah you really need to learn a framework. FW/1 will do what you want and it's easy to learn. I believe Coldbox has a minimalist version also.

<cfinclude> will work on any file with any extension. As a standard practicce, I name all my includes *.cfi.

In the FW/1 world this is particularly useful.

I can have directory with

views/reports/home.cfm
views/reports/details.cfm
views/reports/header.cfi

Valid links include

index.cfm/reports/home
index.cfm/reports/details

But

index.cfm/reports/header

does nothing

Doing this communicates to other developers what I intend for the file to do.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top