Skip to main content
BreakawayPaul
Inspiring
July 22, 2014
Question

Using IsDefined()

  • July 22, 2014
  • 3 replies
  • 798 views

I have a web app that deals with both authenticated users (who log in via a central login) and unauthenticated ones.

For the authenticated ones, I call a web service that returns an XML file.  I'm using this code:

<cfif IsDefined("session.loginauth")>

    <cfset session.logincreds = XMLParse(session.loginauth)>

        <cfset session.userid = session.logincreds.user.row[1].user_id.XmlText>

        <cfset session.rights = session.logincreds.user.row[1].user_type.XmlText>

        <cfset session.usernm =  session.logincreds.user.row[1].name_first.XmlText & " " & session.logincreds.user.row[1].name_last.XmlText>

</cfif>

It works fine for authenticated users, but fails for unauthenticated ones.  The error is on the line with the XMLParse().  It's like the IsDefined isn't working and the code within the cfif is firing no matter what.

I've tried cfparam'ing that session variable like this:

<cfparam name="session.loginauth" default="">

Then:

<cfif session.loginauth neq "">

But that's no better.

Why on earth is that cfif always executing?  If I dump session.loginauth when a user's not logged in, I get nothing.

    This topic has been closed for replies.

    3 replies

    BKBK
    Community Expert
    Community Expert
    July 23, 2014

    BreakawayPaul wrote:

    Why on earth is that cfif always executing?  If I dump session.loginauth when a user's not logged in, I get nothing.

    The cfif continues to execute because session.loginauth exists. Remember that a variable can exist and still be 'nothing'.

    You could consider this issue a blessing in disguise. If you want session.loginauth to exist only when the user is authenticated, then the design needs improving. Instead of cfparam'ing the variable, you should actually delete it. Something like

    <cfif session.loginauth is "">

    <cfset isDeleted = structDelete(session, "loginauth")>

    </cfif>

    Even better, you should go back to the section of code that defines the variable, and make sure it doesn't run when the user is unauthenticated.

    BreakawayPaul
    Inspiring
    July 23, 2014

    Well here's the thing.  When a user logs in, I get an XML string from the authentication server, which I assign to session.loginauth.  I do this using a cfinvoke tag that calls a web service.

    When a user arrives without logging in, session.loginauth is null.  What I want to do is only run the XML parse when session.loginauth contains the XML data from the authentication server, but it seems to run no matter what.

    My understanding is that if I cfparam something (even to "") it''s then defined, so isDefined won't work.  So I can either cfparam it to "" and test against "", or leave it alone and use IsDefined.  Right now neither seem to work.  The odd thing is, this code has been working for over 2 months and just started to fail yesterday morning.

    Right now my workaround is to wrap the cfinvoke and entire cfif block from my original post in a try/catch block, with the catch being empty.  This seems to avoid the error message for non logged in users.  But I still can't figure out why <cfif IsDefined("foo") runs when foo isn't defined.  Or at least I don't see how or where it's defined.

    I used to use StructKeyExists() all the time, but for some reason a bunch of the apps I used it on started throwing errors. Having all these dissimilar systems having to talk to each other is a real challenge.  A few years ago I had standalone systems using cflogin and had zero problems, but now I have to use these web services, and it's introduced elements that I can't control as well.

    BKBK
    Community Expert
    Community Expert
    July 23, 2014

    BreakawayPaul wrote:

    Well here's the thing.  When a user logs in, I get an XML string from the authentication server, which I assign to session.loginauth.  I do this using a cfinvoke tag that calls a web service.

    When a user arrives without logging in, session.loginauth is null.

    That is what I mean by the blessing in disguise. The code is telling you otherwise: session.loginauth exists. Perhaps initialized in onSessionStart?

    What I want to do is only run the XML parse when session.loginauth contains the XML data from the authentication server, but it seems to run no matter what.

    My understanding is that if I cfparam something (even to "") it''s then defined, so isDefined won't work.  So I can either cfparam it to "" and test against "", or leave it alone and use IsDefined.  Right now neither seem to work.

    The code snippet I gave is a good workaround.

    The odd thing is, this code has been working for over 2 months and just started to fail yesterday morning.

    Right now my workaround is to wrap the cfinvoke and entire cfif block from my original post in a try/catch block, with the catch being empty.  This seems to avoid the error message for non logged in users.  But I still can't figure out why <cfif IsDefined("foo") runs when foo isn't defined.  Or at least I don't see how or where it's defined.

    Then it means that, yesterday morning, something happened to the code to make session.loginauth exist for unauthenticated users. As Sherlock Holmes said, "When you have eliminated the impossible, whatever remains, however improbable, must be the truth".

    I used to use StructKeyExists() all the time, but for some reason a bunch of the apps I used it on started throwing errors. Having all these dissimilar systems having to talk to each other is a real challenge.  A few years ago I had standalone systems using cflogin and had zero problems, but now I have to use these web services, and it's introduced elements that I can't control as well.

    Perservere. Software integration is always a challenge. On the plus side, it makes your system infinitely more scalable than cflogin would.

    Participating Frequently
    July 23, 2014

    "If I dump session.loginauth when a user's not logged in, I get nothing."


    Define 'nothing'... do you mean an empty string (implying that perhaps your <cfparam ... default=""> has occurred)?  Or it doesn't exist (which would throw an error when you then tried to cfdump it).

    XMLParse expects an XML string... an empty string will cause it an error.  cherdt's suggestion is one way, but I'd also try finding where you're defaulting it and make sure it's defaulted to an XML string (or removing the defaults entirely).

    Also instead of isDefined it's generally considered preferable to use structKeyExists:

    1. <cfif structKeyExists(session, "loginauth") AND isXML(session.loginauth)> 
    cherdt
    Inspiring
    July 22, 2014

    Sounds like session.loginauth is set to an empty string, if you dump it and get nothing (it should throw an error if you try to dump an undefined variable).

    You could test to see if it is valid XML:

    <cfif isDefined("session.loginauth") AND isXML(session.loginauth)>