hi there I was wondering whether you could try to help me. I am trying to develop a basic login page, and set a session once the login is accepted. I am getting a haringeydsn is not defined in my Application.cfm error? here is the code for application.cfm <cfapplication name = "haringey" sessionTimeout = "#CreateTimeSpan(0,0,45,0)#" sessionManagement = "Yes"> </cfapplication> <cfset haringeydsn = "rugby"> My index file looks like this: <cfif isDefined("url.login")> <cfquery name="ChkUser" datasource="#haringeydsn#"> SELECT AdminID, AdminUsername, AdminPassword, AdminRights FROM Admin WHERE AdminUsername = '#form.username#' AND AdminPassword = '#form.password#' </cfquery> <cfif #ChkUser.recordcount# eq 1> <!--- check password case ---> <cfset comparison = compare(form.password,ChkUser.AdminPassword)> <cflocation url="index.cfm?case"> <cfif comparison eq 0> <!--- all good create session---> <cflock timeout="15"> <cfset SessionLog = StructNew()> <cfset SessionLog.uid = #ChkUser.AdminID#> </cflock> <cfelse> <!--- error page---> <cflocation url="index.cfm?error"> </cfif> <cfelse> <!--- return to login page with error ---> <cflocation url="index.cfm?error"> </cfif> </cfif> <cfinclude template="header.cfm"> <cfform name="loginform" action="index.cfm?login" method="POST" preservedata="Yes"> <table width="500" align="center" cellpadding="0" cellspacing="0" border="0"> <cfif isDefined("url.error")> <tr> <td colspan="2">There has been a problem with your login.</td> </tr> <tr> <td colspan="2"><hr color="#000000"></td> </tr> <cfelseif isDefined("url.case")> <tr> <td colspan="2">Your password is incorrect.</td> </tr> <tr> <td colspan="2"><hr color="#000000"></td> </tr> </cfif> <tr> <td>User Name:</td> <td><cfinput type="text" name="username" required="yes" message="Please enter a user name"></td> </tr> <tr> <td>Password:</td> <td><cfinput type="password" name="password" required="yes" message="Please enter a valid password"></td> </tr> <tr> <td colspan="2"> </td> </tr> <tr> <td colspan="2"><cfinput type="Submit" name="Submit" value="Submit"></td> </tr> </table> </cfform> <cfinclude template="footer.cfm"> I thought if you set a variable in the application.cfm it is global? Also could you suggest whether the above is 'good programming practise'? If not, please suggest a better way. thanks in advance michael
OK,... it seems like you are learning the main points of the application.cfc component. Let me explain what I did, which works for me, and you can decide whether it will fit your needs. I will show you simply how to create it so your login works without errors. application.cfc: <cfcomponent output="no"> <!-----initializes the sessionmanagement---------> <cfset this.sessionmanagement="yes"> <cfset this.sessiontimeout=CreateTimeSpan(0,0,5,30)> <!----Place functions in here that you want to execute every time the application begins---> <cffunction name="onApplicationStart"> </cffunction> <!----Place functions in here that you want to execute every time the session begins---> <cffunction name="OnSessionStart" returntype="void"> </cffunction> <cffunction name="OnRequestStart"> <cfargument type="String" name="index" required="true"/> <cfset application.dataSource = "YOURDATABASE"> <cfset dbdsn = "YOURDSN"> <cfreturn true> </cffunction> <cffunction name="onSessionEnd"> </cffunction> Code (markup): Now, there's not much in this app file, but the main point is that session management is turned on. So, essentially, your website is set up to ALLOW for sessions to occur. Here is what I put on pages that I want secure. I put it at the top, since browsers read code from top to bottom: <cfif not isDefined("SESSION.auth.USER_NAME_NAME")> <h1>Secure Page</h1> <BR /> <p>You are attempting to access a secure page. </p> <p>Please <cfoutput><a href="login.cfm?page=#CGI.SCRIPT_NAME#">login</a></cfoutput> to gain access. If you already have, <A HREF="javascript:history.go(0)">Click here to refresh the page</A>. <cfelse> rest of page code... </cfif> Code (markup): What this does, is it first checks if the variable SESSION.auth.USER_NAME_NAME exists. Well, if no session has been initiated yet, no SESSION.____ variables exists yet at all. So, instead of showing the rest of the page, it tells you to login in. So the user will click the login.cfm link, and go to login.cfm. Login.cfm: <p>Please login below:</p><cfoutput> <!----the reason for the ?page... is so the browser remembers where you came from---> <form method="post" action="login.cfm?page=#URL.PAGE#"></cfoutput> <table width="60%" align="left" cellpadding="0" border="0"> <tr> <td> <p>Username: </p></td> <td> <input type="text" name="username_name"> </td> </tr> <tr> <td> <p>Password: </p></td> <td> <input type="text" name="password_pass"> <input type="submit" value="Log In" /> </td> </tr> </table> </form> <br /> <br /> <br /> <br /> <cfif IsDefined("FORM.USERNAME_NAME")> <cfquery datasource="YOURDATABASE" name="user_check"> SELECT USER_NAME_NAME, USER_PASS_PASS FROM TBLUSER WHERE USER_NAME_NAME = '#FORM.username_name#' AND USER_PASS_PASS = '#FORM.password_pass#' </cfquery> <cfif user_check.recordcount eq 1> <p> <cfoutput> <cfset SESSION.auth = structNew()> <cfset SESSION.auth.isLoggedIn = "Yes"> <cfset SESSION.auth.USER_NAME_NAME = #form.username_name#> <cfquery name="userdata" datasource="YOURDATABASE"> SELECT * FROM TBLUSER WHERE USER_NAME_NAME = '#SESSION.auth.USER_NAME_NAME#' </cfquery> <cfset SESSION.auth.USER_ID = #userdata.USER_ID#> <cfset SESSION.auth.USER_FIRST_NAME = #userdata.USER_FIRST_NAME#> <cfset SESSION.auth.USER_LAST_NAME = #userdata.USER_LAST_NAME#> <cfset SESSION.auth.USER_PASS_PASS = #userdata.USER_PASS_PASS#> <cflocation url="#URL.PAGE#"></cfoutput> <cfelse> <br /><p>Sorry! Your login information is invalid. Please either <a href="register.cfm">Register</a> or visit the <a href="forgotten_password.cfm">Login Retrieval page</a> to find out your login information.</p> </p></cfif> </cfif> Code (markup): Now granted, this will work assuming your database is set up properly (loaded properly in CF administrator), and that your user table is TBLUSER and your fields are what I used. Tweak it to your liking. This should get you on track. I know it's a lot to digest, but just ask if you need clarification for anything.
Unless you scope the <cfset haringeydsn = "rugby"> as an application variable (application.haringeydsn), it's not an application variable. You're setting haringeydsn in application.cfm, but it's only local to that file because it's not scoped as a request, application, cookie or session scope. Then, when you go to call it in index.cfm, index.cfm can't find it. For fun, set session.haringeydsn = "rugby" in your application.cfm, and then in index.cfm, use #session.haringeydsn# in your cfquery. You'll actually really want to set this as an application variable and use cflock it when setting it, but this gets you on the right track.
If you are running on CFMX 7 server then I suggest you follow what lespaul00 is saying. phydiux is correct though. Since you have defined that dsn var in the application file you have to refer to it in all the other files as #application.haringeydsn# Do a search on the livedocs application variables... Also search the application.cfc file as lespaul00 described above. Good luck there is a lot of great information in this post... Take Advantage.
That is simply not true. If you are using Application.cfm (for some reason! ) you can set variables into the variables and/or request scope that can be accessed downstream depending on your approach. However.... use Application.cfc. I typically have something like this in my onRequestStart() method if I am setting some type of application scoped thing like you are talking about: <cfif NOT StructKeyExists(application,"Settings")> <cflock type="exclusive" name="#application.ApplicationName#" timeout="5"> <cfif NOT StructKeyExists(application,"Settings")> <cfset application.Settings = StructNew() /> <cfset application.Settings.Datasource = "whateverdsn" /> <cfset application.Settings.Otherstuff = "Some other stuff..." /> <!--- and so on..... ---> </cfif> </cflock> </cfif> Code (markup): The double condition makes sure that on application init, two simultaneous processes don't battle it out and you have a threading concern. Obviously with something like this where you are dealing with a static value that is not much of a concern, but when you are initializing singleton objects in your application at application init time you can start seeing some unexpected results on heavily loaded apps. Regardless, it is considered best practice when setting application variables. The only exception to this is within the onApplicationStart() method which is inherently thread safe. So, with that said, when you want to access that value later in your app you simply call #application.Settings.Datasource# hth