How to reliably check if the "JSESSIONID" cookie was set in the client browser?

Hello,

I’m using “jee” sessions and I’m looking for a way how to reliably check if the “JSESSIONID” cookie was set in the client browser within the first page request. My app opens in an iframe (different domain) and I need this to check if the user’s browser accepts “third-party cookies”.

For example, if the browser allows “third-party cookies” and the “JSESSIONID” cookie was set correctly, the following code will unfortunately still not work within the first page request. It almost seems as if the “JSESSIONID” cookie is not set in the “onSessionStart()” function in the client browser, but at a later time. I think “onSessionStart()” should be executed BEFORE “onRequestStart()”, right?!

This code does not work within the first page request:

<!--- FILE: Application.cfc --->
<cfcomponent output="false">

	<!--- Debugging: ON --->
	<cfsetting showDebugOutput="Yes">

	<cfscript>
		this.name = "Test-App";
		this.applicationTimeout = createtimespan(0,0,2,0);

		this.sessionManagement = true;
		this.sessiontype = "jee";
		this.sessionStorage = "memory";
		this.sessiontimeout = createtimespan(0,0,1,30);
		this.sessioncookie.samesite = "None";

		this.clientManagement = false;
		this.setClientCookies = false;

		this.scriptProtect = "All";
		this.setDomainCookies = false;
	</cfscript>
</cfcomponent>
<!--- FILE: test.cfm --->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Cookie test for JSESSIONID - test.cfm</title>
</head>
<body>
	<div>
		<cfif	isDefined("COOKIE.JSESSIONID")>
			JSESSIONID cookie was found !
		<cfelse>
			JSESSIONID cookie was <u>NOT</u> found !
		</cfif>
	</div>
</body>
</html>

I would be happy if anyone could help me with that.

Don’t forget to tell us about your stack!

OS: Debian 9.13 - Linux
Java Version: openjdk version “11.0.13+8”
Tomcat Version: 9.0.56
Lucee Version: Lucee 5.3.8.206

Knut, this is a classic problem, which is indeed challenging and there are various possible solutions. I’ll let others propose what’s worked best for them.

But note first that you will NOT be able to detect cookie support on the very FIRST page request someone ever makes to your site, at least not from the server code alone. The problem is that when someone visits your site for the very first time, there will BE no session cookie (jsessionid, in your case). So Lucee (or ACF) would SET it, to be delivered in the first RESPONSE.

Only after they get that response and try to visit a second page could you even try to detect if the cookie was sent BACK. This was a more frequent challenge years ago when some people and orgs blocked all cookies. It’s now returned with some choosing to reject a given site’s cookies when offered via the pop-ups made popular by the gdpr. (It’s not as much affected by third-party cookie issues, as your site would be a first party.)

So bottom line, you need to have sent a response to be able to test if you got it…and that’s challenging.

While some good news is that modern browsers offer Javascript properties reporting cookie support, again you need to send the js code to the browser and have it execute in order to detect that, so it doesn’t really help with the VERY first page request. But you can play tricks with iframes, frameworks, etc. Again, I’ll leave it to others to elaborate on what’s worked well for them.

I just wanted to address first these foundational technical points. And finally, you ask about onsessionstart but you don’t show using it. To be clear, that WOULD show a cookie.jsessionid, but that would be reflecting what Lucee/ACF had SET a) in memory for that first request AND b) as a header which would be sent to the browser in response to that. Again you could NOT use that variable’s presence to know if the cookie was sent FROM the browser. FWIW, the cookies coming IN on a request can be found in the cgi scope’s http_cookie variable.

Hope all that’s helpful. Sorry it couldn’t be a Twitter/Slack-sized reply. Maybe someone else will do that job better, or can with these details our of the way. :slight_smile:

@carehart I don’t like Twitter/Slack exactly because of that and always appreciate your postings here. I’m on slack, but I don’t like that medium because of lack of persistance and searchability. I use this Lucee forum also as some sort of documentation.

@Knut I had a similar issue once with cookie detection, but that was some time ago. what I did was some kind of cookie checker . Basically it was a template that would set a cookie and then auto reload with:

<meta http-equiv=”refresh” content=”2" />

Not the nicest, but that was back 10 years ago and it worked pretty well. It’s not 100% foolproof, but I did well at that time.

What comest to my mind now: Today I’d try it with an embedded iframe, where the main page would set the cookies, and the template in the iframe would then make a second request to another template for checking for that cookie. If it’s available you can break out of that iframe and redirect to another page with javascript.

For third party cookies I’d use the same technique, but with the difference that I’d use a second own (different) domain for that hosted on the same machine. But you might need to set up same-origin specs to avoic cross origin browser problems. But since you are owner of both domains, that can may work.

Alternatively to those iframes, you could even embbed an image with a cfml template, e.g. <img src="imageCookieTest.cfm"... and in that imageCookieTest.cfm you could test for cookies. I have multiple ideas, but I’d need to check for the best solution.

Hello Charlie, hello Andreas,

thank you for your helpful comments on the cookie problem I mentioned. I now understand why it can’t work the way I thought it would (I should have figured that out myself :-).

Under ACF, it would be very easy to check whether the client browser accepts cookies (also “third-party cookies”) or not, because under ACF…

<cfoutput>#isBoolean(URLSessionFormat("true"))#</cfoutput>

…returns either “true” or “false” (alternatively “yes” or “no”). Lucee, on the other hand, always returns “false” because the “URLSessionFormat()” function doesn’t work correctly. See https://luceeserver.atlassian.net/browse/LDEV-3707

I’ll probably have to fall back on a very old solution that I used many years ago for another project, but which at least works reliably as a workaround.

Thank you for your prompt help and your explanations.

Best regards
Knut

I don’t think that would be a very reliable working cookie detector, because:

  1. that function expects an URL string, not a boolean as string.

  2. The function outputs an URL string with an appended url session token if it doesn’t see the session cookies in the request heades. That means: you must make sure to use that code always in the second request, but that code won’t work within the first request.

  3. Don’t know how that would work, because that code should only convert the output string to a boolean, what from my understanding would always be true.

  4. This solution sticks to enabled session managment but you may also want to check for any cookies and not cfml specific session cookies, even if you have session management disabled. But ok if you just want to test if your session management cookies are enabled.

Just posting a simplistic example how to test cookies with an iframe. However, you’ve said you want to do it within the first request. That won’t be possible. But I’m posting this here for any others that might need something similar.

<!--- cookietest.cfm --->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Cookie tester</title>
</head>
<body>
	<div>
        <cfset cookieName="myCookieTest">
        <cfset cookieValue=hash(now())>
        <cfcookie name="#cookieName#" value="#cookieValue#">
        <cfoutput>
        <iframe src="cookiecheck.cfm?cname=#urlencode(cookieName)#&cvalue=#urlencode(cookieValue)#" name="cookieFrame"></iframe>
        </cfoutput>
    </div>
</body>
</html>


<!--- cookiecheck.cfm --->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Cookie Check</title>
</head>
<body>
	<div>
        <cfif structKeyExists( url, "cname" ) and structKeyExists( url, "cvalue" )> 
            <cfif structKeyExists(COOKIE, url.cname) and cookie[  url.cname ] is url.cvalue>
                Cookies activated!
            <cfelse>
                Cookies deactivated!
            </cfif>
        <cfelse>
            cookie data not specified in URL
        </cfif>
	</div>
</body>
</html>

Run it and call cookietest.cfm

Thanks, Andreas and Knut. And I agree with A’s assessment of why the urlsessionformat would not seem at all a suitable solution, but especially on the first page visit which was a fundamental need for you, Knut. Let’s see if the code Andreas or anyone else offers may suit you.

I really don’t think that’s possible, because as you’ve already mentioned, cookies are added after receiving them as server response headers to the browsers request headers.

Andreas, you’re right. I just tested this under ACF and it only works from the second request.

Thank you very much for your “iFrame” code example.

My ticket system is accessed via JavaScript from various websites of my system customers and is then displayed in a lightbox (in an iFrame). I had already integrated a solution into the caller JavaScript last night because I hadn’t read your post until then. But my solution also seems to work fine.

Nevertheless, thank you very much for your iFrame code example and your support.

1 Like

@Knut something very important aspect I’d like to mention is that Lucee won’t create any default session cookies at all if you don’t set a session variable. Only when the session scope is populated it sets a cookie.

1 Like

Thank you, I am aware of that.

Right, Andreas. I was 100% agreeing with you. I was just stressing that while urlsessionformat might have some unexpected value related to the question of whether sessionid cookies were passed in, it would not help for Knut’s primary need.

1 Like