Skip to content

Instantly share code, notes, and snippets.

@JamoCA
Last active June 24, 2024 19:18
Show Gist options
  • Save JamoCA/fd43c189379196b6a52884affea3ad51 to your computer and use it in GitHub Desktop.
Save JamoCA/fd43c189379196b6a52884affea3ad51 to your computer and use it in GitHub Desktop.
ColdFusion UDF to temporarily cache data and return a UUID. Good for verifying form posts (ie, like CSRF) or building magic link passwordless logins for monolith web application.
<!--- tempCache UDF (2019-11-22) By SunStar Media
ColdFusion UDF to temporarily cache data and return a UUID. Used for verifying form posts (ie, like CSRF) or building magic
link passwordless logins for monolith web application.
GIST: https://gist.github.com/JamoCA/fd43c189379196b6a52884affea3ad51
Twitter/X: https://x.com/gamesover/status/1803866104491839620
Blog: https://dev.to/gamesover/tempcache-coldfusion-udf-32f9
--->
<cfscript>
public any function tempCache(
any inputObject,
numeric minutes=5,
numeric maxMinutes=5,
boolean singleUse=false,
string cachePrefix="tempCache_"
) hint="Temporarily cache data for x minutes. (Pass object; returns UUID. Pass UUID, returns object.)" {
local.response = "";
local.minutes = (val(arguments.minutes) gt 0) ? val(arguments.minutes) : 5;
local.maxMinutes = abs(val(arguments.maxMinutes)) + local.minutes;
if (issimplevalue(arguments.inputObject) && isvalid("UUID", arguments.inputObject)){
local.response = cacheget("#arguments.cachePrefix##arguments.inputObject#");
if (isnull(local.response)){
local.response = {};
} else if (arguments.singleUse){
cacheremove("#arguments.cachePrefix##arguments.inputObject#");
}
} else {
local.response = createuuid();
cacheput("#arguments.cachePrefix##local.response#", arguments.inputObject, createtimespan(0, 0, local.maxMinutes, 0), createtimespan(0, 0, local.minutes, 0));
}
return local.response;
}
</cfscript>
<cfparam name="url.Token" default="">
<cfset tempConfig = [
"inputObject": [
"html": "<p>Hello World #datetimeformat(now(), "iso")#</p>",
"IPAddress": CGI.REMOTE_ADDR,
"timestamp": datetimeformat(now(), "iso")
],
"minutes": 5,
"maxMinutes": 5,
"singleUse": false
]>
<h2>tempCache Demo</h2>
<cfif len(url.Token)>
<fieldset>
<cfoutput>
<legend>Fetching "#url.Token#" from tempCache UDF</legend>
</cfoutput>
<cfif isvalid("UUID", url.Token)>
<cfset cacheResults = tempCache(url.Token)>
<cfif !structcount(cacheResults)>
<p style="color:red;"><b>No results.</b> Cache key doesn't exist</p>
<cfelseif !cacheResults.keyexists("IPAddress")>
<p style="color:red;"><b>Suspicious:</b> Cache key exists, but not IP address.</p>
<cfelseif cacheResults.IPAddress neq CGI.REMOTE_ADDR>
<p style="color:red;"><b>Suspicious:</b> IP address exists, but not same as current request.</p>
<cfelse>
<p style="color:green;"><b>Good:</b> IP address exists and is the same as current request.</p>
</cfif>
<cfoutput>
<p><b>Retry Token:</b> <a href="?Token=#url.Token#">#url.Token#</a></p>
</cfoutput>
<cfdump var="#cacheResults#" label="Cached data for #url.Token#">
<cfelseif len(url.Token)>
<p style="color:green;"><b>Invalid:</b> ID is not a UUID</p>
</cfif>
</fieldset>
</cfif>
<cfset newToken = tempCache(argumentcollection=tempConfig)>
<cfoutput>
<fieldset>
<legend>New Token:</legend>
<p><a href="?Token=#newToken#">#newToken#</a></p>
<cfdump var="#tempConfig#" label="New ID Config (debugging)">
</fieldset>
</cfoutput>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment