ColdFusion check when cookie expires - coldfusion

Is it possible to check when a cookie is due to expire? I have tried the following:
First I set three cookies:
<cfcookie name="test1" value="" expires="10" />
<cfcookie name="test2" value="" expires="never" />
<cfcookie name="test3" value="" expires="now" />
Then on another page I check the cookie data:
<cfset cookies = getPageContext().getRequest().getCookies()>
<Cfoutput>
<cfloop index="c" array="#cookies#">#c.getName()#:#c.getMaxAge()#<br>
</cfloop>
</Cfoutput>
However MaxAge returns -1 for all cookies instead of the actual expiration date. How can I get the actual expiration date?

Attempting to answer this question (only because this is a ColdFusion question and I thought it would be rude to mark this a duplicate of a Java question without discussing it.) without completely plagiarizing this Java answer.
getPageContext().getRequest().getCookies() this basically gets you the cookies that were sent to the server by the browser. The browser only sends back the name and value of the cookie. So once the cookie is set, there is no way for the server to know when that Cookie is going to expire. You might need to save the cookie expiry on the server side when you are setting it.

Related

Variable session passes from page to page coldFusion

CFBuilder admin storage
15cdb5dcb6.jpg
Application.cfm
34ed7586e1.jpg
Login.cfm
<cfif not isDefined('FORM.submitButton')>
<cfform name="loginForm" method="post" action="#CGI.SCRIPT_NAME#">
Login:
<cfinput type="text" name="login" required="yes">
Password:
<cfinput type="password" name="password" required="yes">
<br>
<cfinput type="submit" name='submitButton' value="Sign">
<br>
<cfinput type="button" name='registerButton' value="Register">
</cfform>
<cfelse>
<cfquery name='getUser' datasource="dbfortest">
SELECT * FROM usertable WHERE login="#FORM.login#" ;
</cfquery>
<cfif getUser.RecordCount NEQ 0>
<cfif FORM.password eq getUser.password>
<cflock scope="Session" timeout="60" type="exclusive" >
<cfset Session.loggedIn = "yes">
<cfset Session.user = "#FORM.login#">
</cflock>
<cfoutput>#StructKeyList(Session)#</cfoutput>
<cfelse>
Your pass isn't correct.
</cfif>
<cfelse>
There is no user with this name.
</cfif>
</cfif>
part of page when i want to use login including.
<cfif Session.loggedIn eq "no">
<cfinclude template="login.cfm">
</cfif>
<cfif structKeyExists(session, "user")>
<cfoutput>Welcome, #Session.user#.</cfoutput>
</cfif>
<cfoutput>#StructKeyList(Session)#</cfoutput>
Hello everyone, please help me understand these sessions' behavior.
The whole problem consists in attempting to pass variables from one page to another.
So after login i don't see the session.user in session struct.
How can i pass this?
Have already tried different browsers.
#Aquitaine has given you some good information. I just wanted to also point out that another part of your problem is likely that you have set a 10 second life span for your sessions. That's probably not long enough.
In the Application.cfm example that you posted you have this line:
sessiontimeout="#createTimespan(0,0,0,10)#"
The arguments for the CreateTimeSpan function are as follows:
createTimespan(days, hours, minutes, seconds)
As such you are assigning a 10 second lifespan for sessions. Perhaps you meant to set 10 minutes instead of 10 seconds.
To figure out what's going on with the session variables, try putting in some debug code right after your cfset session statements to make sure that they're happening. Maybe <cfdump var="#session#">.
You do not need to cflock your session scope (and have not needed to since CFMX). See Adam Cameron's 2013 post on when to lock scopes
If your debug code runs and you see the session variables, but then they're gone on the next page, that may be an issue with your session storage (which is a different part of cfadmin) or else whatever front-end webserver you're using. Try <cfdump var="#session#"> in onRequestStart in Application.cfc and make sure that JSESSIONID is the same on every request. (or try disabling J2EE session variables in CFADMIN and see if the same problem persists with CFID/CFTOKEN).
If your debug code doesn't run, then you should be seeing one of your error conditions.
For ease-of-reading, be consistent in your casing when refering to scopes, e.g. session not Session. While this kind of thing may not matter functionally, it can get you into trouble with portability when referencing paths or components.
Some other issues:
If you are going to use a boolean value for loggedIn then use a boolean value: true or false or 1 or 0 or (if you must) yes or no but not "yes" which is a string; instead of being able to do if (session.loggedIn) if you will have to do if (session.loggedIn == 'yes') and nobody will be happy.
If this is meant to be working, production site code, at a minimum you need to be using cfqueryparam as you do not ever want to pass unescaped user input directly to a database query.
You might also head over to the CFML slack at cfml.slack.com and ask on #cfml-beginners for some pointers on writing login forms.

grabbing JSON data using coldfusion

I have a URL which when run in the browser, displays JSON data, since I am new to coldfusion, I am wondering, what would be a good way to
grab the data from the web browser? Later on I will be storing the individial JSON data into MySQL database, but I need to figure out step 1
which is grabbing the data.
Please advise.
Thanks
You'll want to do a cfhttp request to load the external content.
Then you can use deserializeJSON to convert the JSON object into the appropriate cfml struct.
See the example Adobe gives in the deserializeJSON documentation.
Here is quick example:
<!--- Set the URL address. --->
<cfset urlAddress="http://ip.jsontest.com/">
<!--- Generate http request from cf --->
<cfhttp url="#urlAddress#" method="GET" resolveurl="Yes" throwOnError="Yes"/>
<!--- handle the response from the server --->
<cfoutput>
This is just a string:<br />
#CFHTTP.FileContent#<br />
</cfoutput>
<cfset cfData=DeserializeJSON(CFHTTP.FileContent)>
This is object:<br />
<cfdump var="#cfData#">
Now you can do something like this:<br />
<cfoutput>#cfData.ip#</cfoutput>
Execute this source here http://cflive.net/

onRequestStart user authorisation does not work correctly coldfusion

Im my Application.cfc I am trying to use the onRequestStart() function to protect my pages as such:
<cffunction name="onRequestStart" access="public" returntype="boolean">
<cfargument type="String" name="TargetPage" required="true"/>
<!--- Define which pages don't need protection --->
<cfset APPLICATION.AllowedPages = "/index.cfm, /register.cfm">
<!--- Create an instance of the page-protect.cfc --->
<cfset APPLICATION.PageProtect = CreateObject("component", "page-protect")>
<!--- check if the current page is an allowed page --->
<cfif #ListFindNoCase(APPLICATION.AllowedPages, ARGUMENTS.TargetPage)# EQ 0>
<!--- if its not an allowed page, then protect it --->
<cfscript>
APPLICATION.PageProtect.PageProtectBasic(argumentcollection = session);
</cfscript>
</cfif>
<cfreturn true>
</cffunction>
This code works (kind of as you will see later). Page-protect.cfc is very simple and does this:
<cfcomponent displayname="page-protect" output="false">
<cffunction name="PageProtectBasic" output="no">
<cfif NOT structKeyExists (SESSION, 'Auth')>
<cflocation url="/index.cfm" addtoken="no">
</cfif>
</cffunction>
</cfcomponent>
So if the Auth structure within the SESSION scope does not exist, then this user is not logged in and should be taken back the homepage. A logout method in a different file deletes the Auth structure from SESSION and also clears the SESSION scope (if definitely does this I have tested it).
The onRequestStart() page protection works initially but I have noticed that when I press the back button on my browser it will show the previous page that I just logged out of. This should be a protected page and not display but I guess its a browser cache so not a problem. However the problem is that if I click on a link in this page it SHOULD not allow it and send the user back to home page (because the SESSION.Auth structure does not exist and SESSION has been cleared). But it does not send the user back to the homepage anymore, it just shows a ColdFusion error page stating that "Element AUTH.{element_name} is undefined in SESSION".
So for some reason its not going back to the homepage despite the user not being logged in, and instead is trying to load the protected page and then falling over because a variable within the SESSION.AUTH structure does not exist. I simply don't understand what I'm doing wrong. Please help!
While James Mohler provides some very helpful pointers on how to improve your code in general the issue you are having is not related to that.
The reason that users can see these pages on hitting back is because they are cached in the browser. This is the browser trying to be helpful and not requesting data from the server that it has already seen. The browser being a good internet citizen will do what it is told though. So you need to return the correct HTTP headers to tell it that you don't want it to cache them. E.g.
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
So to do this in CF
<cfheader name="Cache-Control" value="no-cache, no-store, max-age=0, must-revalidate">
<cfheader name="Pragma" value="no-cache">
If you add the above to the pages that are concerning you, the problem will go away.
Simon
Sorry, this won't fit into a comment box
I think what you are trying to do is something like this:
onApplicationStart() {
APPLICATION.PageProtect = CreateObject("component", "page-protect")>
}
onSessionStart() {
session.auth = false; // it is easier to work with if it always exists
}
onRequestStart() {
if (ListFindNoCase(APPLICATION.AllowedPages, ARGUMENTS.TargetPage) EQ 0)
// if its not an allowed page, then protect it
APPLICATION.PageProtect.PageProtectBasic(argumentcollection = session);
}
}
Possibly not related to your problem but this line might have a couple of issues.
<cfset APPLICATION.AllowedPages = "/index.cfm, /register.cfm">
Issue number 1 is the leading slashes. Unless arguments.TargetPage has those slashes, and they might, you are not going to get the expected behaviour.
Issue number 2 is the space between your two list items. Leading spaces are part of the list item which could lead to unexpected behaviour on register.cfm.

How to delete a client-side cookie when I access a certain page?

I am trying to delete a client-side cookie when I access a certain page. How to I do this? Even after using the code below, I'm unable to delete the client side cookie:
<cfcookie name="GIFT CAT" value="" expires="NOW" />
<cfset StructDelete(cookie, 'GIFTCAT', false)>
You need to make sure all attributes are the same as on the set cookie. So secure, domain and path specifically.
<cfcookie name="test1" value="1" domain="test.com" />
<cfcookie name="test1" value="" expires="now" />
doesn't work, but
<cfcookie name="test1" value="1" domain="test.com" />
<cfcookie name="test1" value="" domain="test.com" expires="now" />
does work.
(Expanded from comments)
It sounds like you are testing the cookie status incorrectly. You cannot do this in a single http request. The http response must be sent back to the browser for the client cookie to actually be deleted. That change will be reflected in the next http request.
when i keep the dump to see the result showing empty string
Also, if you review the ColdFusion documentation it states that expire="now" does not delete the corresponding variable [from] the Cookie scope of the active page). So if you delete a cookie, then dump the cookie scope on the same page, the deleted cookie will still exist. In your case the value will be an empty string.
Properly testing the behavior requires three requests:
Create the cookie:
<cfcookie name="GIFT_CAT" value="Created cookie at #now()#"/>. After running the script in your browser, "GIFT_CAT":
Exists in the CF cookie scope
Exists in browser cookies
Delete the cookie: <cfcookie name="GIFT_CAT" value="" expires="NOW" />. After running the script in your browser, "GIFT_CAT":
Still exists in the CF cookie scope (because expire does not delete it on the active page)
Does NOT exist in browser cookies (because the browser deletes the cookie after receiving the response)
Finally, verify the cookies: <cfdump var="#COOKIE#">. After running the script in your browser, "GIFT_CAT":
Does NOT exist in the CF cookie scope
Does NOT exist in browser cookies

Cflocation bug / new feature in ColdFusion 9 - URL appending twice

When a user logs in and is redirected to a secured page, the url is getting appended twice like a list. This in turn causes a 404.
(example: http://uwf.edu/something.cfm,http://uwf.edu/something.cfm)
Currently, the site has a custom login tag which I am unable to edit as I do not have control over it. (It's just a custom cf tag that allows people to login at the university.)
I have to do additional processing after this tag to verify that they are eligible to login on this particular site. Once they have been verified, they are re-directed to another page with cflocation.
<custom login tag>
<cfinvoke component="#application.path#cfc/security" method = "constructSession" returnvariable = "status">
.. params excluded..
</cfinvoke>
<cfif status eq 1>
<cflocation url="#someurl_invalid#" addtoken="no" />
<cfelse>
<cflocation url="#someurl#" addtoken="no" />
</cfif>
The custom login tag refreshed the current page already, but I obviously do not want that and thus had used the above method to re-direct. This worked in ColdFusion 8.
I read this article: http://www.bennadel.com/blog/2050-Changes-In-CFLocation-OnRequestEnd-Behavior-In-ColdFusion-9-s-Application-cfc.htm
The article gave me some insight as to what is going on...but I am unsure how to fix the issue.
Does anyone have any solutions?
Since you don't have control over the custom tag, you'll have to work around the issue instead of fixing it.
I would recommend changing the code:
<cfif status eq 1>
<cflocation url="#ListFirst(someurl_invalid)#" addtoken="no" />
<cfelse>
<cflocation url="#ListFirst(someurl)#" addtoken="no" />
</cfif>
It's not pretty but will work whether the URLs are lists or not.