seems i am getting on a very simple page in my App...
# cfml-general
g
seems i am getting on a very simple page in my Application.cfc, i wan to keep sessions for all pages except the one i listed as publicpages <!--- List of pages that don't require authentication ---> <cfset var publicPages = "login.cfm,register.cfm,registerSubmit.cfm,logout.cfm,login_check.cfm"> <!--- Check if the current page is public ---> <cfif listFindNoCase(publicPages, listLast(arguments.thePage, "/"))> <cfreturn true> </cfif> <!--- Check if user is logged in ---> <cfif structKeyExists(session, "loggedin") AND session.loggedin eq false> <cflocation url="login.cfm" addtoken="false"> </cfif> <!--- Validate user's role for the requested page ---> <cfset var allowedAccess = application.auth.checkUserAccess(session.role_id)> <cfif NOT allowedAccess> <cflocation url="unauthorized.cfm" addtoken="false"> </cfif> <!--- Rotate session ID to prevent session fixation ---> <cfset sessionRotate()> but it seems when i logout and login back, the login check is going to 302 adn i stay at login screen , what is wrong i am doing here
n
You're changing the sessionID via sessionRotate() on every request.
g
That is why it is doing it ? I am not sure I was thinking the session rotate should have some added functionality
How about if I put that session rotate not within the public pages
b
What if
session.loggedId
does not exist? Did you perhaps intend to do something like the following?
<!--- Check if user is not logged in --->
<cfif NOT structKeyExists(session, "loggedin") OR (structKeyExists(session, "loggedin") AND session.loggedin eq false)>
<!--- Rotate session ID to prevent session fixation --->
<cfset sessionRotate()>
<cflocation url="login.cfm" addtoken="false">
</cfif>
<!--- Validate user's role for the requested page --->
<cfset var allowedAccess = application.auth.checkUserAccess(session.role_id)>
<cfif NOT allowedAccess>
<cflocation url="unauthorized.cfm" addtoken="false">
</cfif>
a
Yeah, the key is where do you set
session.loggedin = true
g
problem is this code <cfif NOT structKeyExists(session, "loggedin") OR (structKeyExists(session, "loggedin") AND session.loggedin eq false)> <!--- Rotate session ID to prevent session fixation ---> <cfset sessionRotate()> <cflocation url="login.cfm" addtoken="false"> </cfif> it never logs me in once i am logged out, it keeps me redirected to same login.cfm evern after entering credentials
a
OK, so first of all - simplify your use of
session.loggedin
. You can either in
onSessionStart
(of Application.cfc) set
session.loggedin = false;
and then set it to true on authentication. That way it always exists so much simpler logic. Alternatively, just check if it exists of not, so login creates the key (value not important) and log out deletes the key.
You then have much cleaner code to read and maintain.
g
its already setup in Application.cfc onsessionstart method as session.loggedin = false
a
So why are you checking it exists?
g
the code i added in the onrequeststart is for the pages which are used after the login and when redirected, in between if session expires it redirects to the login screen, but when it logs out, and it then unable to login back
i can share more code if needed, let me knw
a
if the session timesout then onSessionStart will run again (as well, there is no session)
Also, this is a perfect example of where writing tests would make your life so much easier 🙂
g
i will list again my onRequestStart
Copy code
<!--- List of pages that don't require authentication --->
  <cfset var publicPages = "login.cfm,register.cfm,registerSubmit.cfm,logout.cfm,login_check.cfm">
  
  <!--- Check if the current page is public --->
  <cfif listFindNoCase(publicPages, listLast(arguments.thePage, "/"))>
      <cfreturn true>
  </cfif>
  
 <!---  <cfif NOT structKeyExists(session, "loggedin") OR (structKeyExists(session, "loggedin") AND session.loggedin eq false)>
  	  <!--- Rotate session ID to prevent session fixation --->
 	  <cfset sessionRotate()>
      <cflocation url="login.cfm" addtoken="false">
  </cfif> --->

  <!--- Validate user's role for the requested page --->
  <cfset var allowedAccess = application.auth.checkUserAccess(session.role_id)>
  <cfif NOT allowedAccess>
      <cflocation url="unauthorized.cfm" addtoken="false">
  </cfif>
on my onSessionStart
Copy code
<cffunction name="onSessionStart" returntype="void">
	<cfset Session.templeNB = StructNew()>
	<cfset Session.templeNB.isSuper = false>
	<cfset Session.templeNB.isAdmin = false>
	<cfset Session.templeNB.isEditor = false>
	<cfset Session.templeNB.ContactID=1>
	<cfset Session.templeNB.ContactName=''>
	<cfset Session.templeNB.ContactFirstLastName=''>
	<cfset Session.templeNB.LoggedIn="False">
	<cfset Session.templeNB.LogInID=0>
	<cfset Session.templeNB.email=''>
  <cfset session.loggedin = false>
  <cfset session.role_id = 1>
  <cfset session.failedLoginAttempts = 0>
  <cfset session.lastLoginAttempt = "">
</cffunction>
i do not rely on cflogin as that is not much secure
a
and I will post again my response 🙂
OK, so first of all - simplify your use of session.loggedin. You can either in onSessionStart (of Application.cfc) set session.loggedin = false; and then set it to true on authentication. That way it always exists so much simpler logic. Alternatively, just check if it exists of not, so login creates the key (value not important) and log out deletes the key. (edited)
Copy code
<!--- List of pages that don't require authentication --->
  <cfset var publicPages = "login.cfm,register.cfm,registerSubmit.cfm,logout.cfm,login_check.cfm">
  
  <!--- Check if the current page is public --->
  <cfif listFindNoCase(publicPages, listLast(arguments.thePage, "/"))>
      <cfreturn true>
  </cfif>
  
  <cfif NOT session.loggedin>
      <cflocation url="login.cfm" addtoken="false">
      <cfreturn true>
  </cfif>

  <!--- Validate user's role for the requested page --->
  <cfif NOT application.auth.checkUserAccess(session.role_id)>
      <cflocation url="unauthorized.cfm" addtoken="false">
      <cfreturn true>
  </cfif>

  <cfreturn true>
I assume you logout.cfm does
session.loggedin = false
?
and your
login.cfm
does
session.loggedin = true
?
I'll also repeat that this is a perfect example of where unit testing is so useful. You can have each scenario as a test and then you know it works.
g
ok, let me rewrite this logic again i want to keep everything in Application.cfc, i can't seem why i am stuck on this, i did this so many timkes
b
Two more remarks: (1) Since onSessionStart contains the setting,
<cfset session.loggedin = false>
, my previous login suggestion is then similar to that of Aliaspooryorik:
<cfif not session.loggedin>
<!--- Rotate session ID to prevent session fixation --->
<cfset sessionRotate()>
<cflocation url="login.cfm" addtoken="false">
</cfif>
(2) Anyway, I suspect that that is probably not the code that keeps sending you back to login.cfm. The culprit is probably
<cfif NOT application.auth.checkUserAccess(session.role_id)>
. It is likely that
session.loggedin
reverts to false within the function
checkUserAccess
If
checkUserAccess()
were false then, presumably,
session.loggedin
could also be reset to false somewhere within the function. That would explain why you keep ending up at login.cfm. So check the code within the function and make sure it does not reset
session.loggedin
to false.
g
I will check that