Skip to main content
Inspiring
August 5, 2011
Answered

Keep Session Alive

  • August 5, 2011
  • 2 replies
  • 3474 views

Step1: A partner firm passes xml values to me via url and thi has a session variable from his server.

Step2: I need to take that xml data and run a query on it to get additional values.

Step3: After the query I need to send back xml to my partner firm, AND I NEED TO KEEP THE SESSION VARIABLE ALIVE FROM WHEN HE SENT IT TO ME in Step 1 and pass back my xml in the same SESSION!!!

Here is the code I have now in Step 3

<cfhttp url="https://partnerfirm.com" method="post">
    <cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">

  </cfhttp>

According to my partner firm my xml is getting back to their server but since I dont have the same SESSION from Step 1 it gets rejected.

I guess the <cfhttp> that I send back in Step 3 starts a new Session...so the original session that oartner sent in Step 1 is gone.

Is there a way to keep the session from Session 1 and use that same session in step 3?

Do I need to use a different tag a different technolgy a different coding language??

I have spent all week on this..this is something that should have taken a few hours.

My Partner firm tells me that other firms/programmers have had no issue implementing this and I must be doing somethin wrong.

I have read the BEN NADEL stuff about this about trying to somehow capture the Session variable in Step 1..then do Step 2....then pass the Session variable back with the xml data....it made sense to me.

But partner firm says that wont work...so I stopped pursuing .

Am I just stupid...Am I missing something..Do I need to buy custom tag???

Any Help???

    This topic has been closed for replies.
    Correct answer 12Robots

    I was gonna give up and cry like a baby . But your offer of help is to good to be true and I think I'll take your help.


    THANK YOU!!!


    Here is the sequence of events.


    Step 1 : HTTP call made to partner site. I pass userid and a token to partner firm via url.

    http://www.partnerfirm.com?userid=#userid#&token=#token#


    Step 2 : Partner send back the same userid and token to a url on my site.

    This is when the partners session starts. This is the session I need to keep alive and respond back with this same session.


    Step 3: I run query against the userid to make sure user is real. If so I then pass this xml back to the partner firm via the cfthhp tag.


    <Response><Header><Status>1</Status></Header></Response>


    When partner gets this xml back they redirect user to a page in the site.


    Partner assures me that I am getting back to his server but that I didnt keep session so i got declined.

    But I'm not 100% sure that the xml is correct.


    I might need to add < ?xml version="1.0" encoding="utf-8"?> to the top of the xml

    See what you think.

    Here is my code

    <!----------- This is the code from Ben Nadel that captures the JSESSIONID ----------->
    <cffunction name="GetResponseCookies" access="public" returntype="struct" output="false">
      <cfargument name="Response" type="struct" required="true" />
      <cfset var LOCAL = StructNew() />
      <cfset LOCAL.Cookies = StructNew() />
      <cfif NOT StructKeyExists(ARGUMENTS.Response.ResponseHeader,"Set-Cookie")>
        <cfreturn LOCAL.Cookies />
      </cfif>
      <cfset LOCAL.ReturnedCookies = ARGUMENTS.Response.ResponseHeader[ "Set-Cookie" ] />
      <cfloop item="LOCAL.CookieIndex" collection="#LOCAL.ReturnedCookies#">
        <cfset LOCAL.CookieString = LOCAL.ReturnedCookies[ LOCAL.CookieIndex ] />
        <cfloop index="LOCAL.Index" from="1" to="#ListLen( LOCAL.CookieString, ';' )#" step="1">
          <!--- Get the name-value pair. --->
          <cfset LOCAL.Pair = ListGetAt( LOCAL.CookieString, LOCAL.Index, ";") />
          <cfset LOCAL.Name = ListFirst( LOCAL.Pair, "=" ) />
          <cfif (ListLen( LOCAL.Pair, "=" ) GT 1)>
            <cfset LOCAL.Value = ListRest( LOCAL.Pair, "=" ) />
            <cfelse>
            <cfset LOCAL.Value = "" />
          </cfif>
          <cfif (LOCAL.Index EQ 1)>
            <cfset LOCAL.Cookies[ LOCAL.Name ] = StructNew() />
            <cfset LOCAL.Cookie = LOCAL.Cookies[ LOCAL.Name ] />
            <cfset LOCAL.Cookie.Value = LOCAL.Value />
            <cfset LOCAL.Cookie.Attributes = StructNew() />
            <cfelse>
            <cfset LOCAL.Cookie.Attributes[ LOCAL.Name ] = LOCAL.Value />
          </cfif>
        </cfloop>
      </cfloop>
      <cfreturn LOCAL.Cookies />
    </cffunction>
    <!----------- This ends the code from Ben Nadel that captures the JSESSIONID ----------->
    <!--- Extracts the text of named XML elements and returns it in a list. --->
    <cffunction name="xmlExtractList" returnType="string" output="no">
      <cfargument name="inString" type="any">
      <cfargument name="tagName" type="string">
      <cfargument name="delim" default=",">
      <cfset var inXML = "">
      <cfset var elementsArray = "">
      <cfset var valuesArray = arrayNew(1)>
      <cfset var i=1>
      <cfset var j=1>
      <cfset var ret = "">
      <cfif isXmlDoc(arguments.inString)>
        <cfset inXML = arguments.inString>
        <cfelse>
        <cfset inXML  = xmlParse(arguments.inString)>
      </cfif>
      <cfset elementsArray = xmlSearch(inXML, "//" & arguments.tagName)>
      <cfloop index="j" from="1" to="#arrayLen(elementsArray)#">
        <cfif elementsArray.xmlText neq "">
          <cfset valuesArray = elementsArray.xmlText>
          <cfset i=i+1>
        </cfif>
      </cfloop>
      <cfset ret = arrayToList(valuesArray, arguments.delim)>
      <cfreturn ret>
    </cffunction>
    <!--- Extracts the text of named XML elements and returns it in a list. --->
    <!----------- This is my code to extract the values from partners xml --------->
    <cfset soapData = GetHttpRequestData()>

    <cfsavecontent variable="soapContent">
    <cfoutput> #toString(soapData.content)# </cfoutput>
    </cfsavecontent>
    <cfoutput>#soapContent#</cfoutput>
    <cfset myString = "#soapContent#" />
    <cfset useridfrompartnerfirm =#xmlExtractList(soapContent, "UserId")#/>
    <cfset tokenfrompartnerfirm =#xmlExtractList(soapContent, "Token")#/>
    <!----------- This ENDS my code to extract the values from partners xml --------->
    <!----------- This is where I run the query to validate the userid pased to me --------->
    <CFQUERY name="Get_User" datasource="#request.dsn#">
    SELECT * FROM users WHERE username = '#useridfrompartnerfirm#'
    </CFQUERY>
    <!----------- This ENDS where I run the query to validate the userid pased to me-------->
    <!----------- This is where I set the xml to be sent back to partner with CFSET tag --------->
    <cfset xml_to_partnerfirm = "<Response><Header><Status>1</Status></Header></Response>" />
    <!----------- This ENDS here I set the xml to be sent back to partner with CFSET tag --------->
    <!----------- If there is a match the user is authenticated and I pass back the xml back to partner via cfhttp --------->
    <cfif Get_User.recordcount EQ 1>
      <cfsavecontent variable="xml_to_partnerfirm">
      <Response>
        <Header>
          <Status>1</Status>
        </Header>
      </Response>
      </cfsavecontent>
      <cfhttp url="https://uat.partnerfirm.com/secure/sso/pk_request.jsp"   method="Post"  >
        <cfhttpparam type="xml" name="XMLUpload" value="#xml_to_partnerfirm#">
            <cfhttpparam type="cookie" name="JSESSIONID" value="#respCookies.JSESSIONID#" />
      </cfhttp>
    </cfif>


    I just went and looked at one of your other posts and saw the XML structure they are passign you.  You may want to try passing back something like:

    <Response>
        <Header>
          <Status>1</Status>

        <Token>#tokenfrompartnerfirm#</Token>

        </Header>

      </Response>

    2 replies

    12Robots
    Participating Frequently
    August 6, 2011

    Typically, to maintain an HTTP session (which is what I am assuming you are talking about) a session token is passed back and forth.  The server that maintains the session (your partner's server, I believe based on your description) expects to receive that token as part of a name/value pair in a typical location. 

    For example, if the maintining server was a CF server it would expect to receive the session token as a set of key/value pairs (CFID and CFToken) in the Cookie, Form, or URL scopes.  So if you were sending to a CF server, it might look like this:

    <cfhttp url="https://partnerfirm.com" method="post">
        <cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">

        <cfhttpparam type="cookie" name="CFID" value="#cfidThatYouWereSentinXML" />

        <cfhttpparam type="cookie" name="CFToken" value="#cfTokenThatYouWereSentinXML" />

    </cfhttp>

    If the server is running a Java application, then you would probably do something like this:

    <cfhttp url="https://partnerfirm.com" method="post">
        <cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">

        <cfhttpparam type="cookie" name="JSESSIONID" value="#JSESSIONIDThatYouWereSentinXML" />

    </cfhttp>

    If it is a PHP server it might look like this:

    <cfhttp url="https://partnerfirm.com" method="post">
        <cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">

        <cfhttpparam type="cookie" name="PHPSESSID" value="#PHPSESSIDThatYouWereSentinXML" />

    </cfhttp>

    And if it is an ASP.NET server, it might look like this:

    <cfhttp url="https://partnerfirm.com" method="post">
        <cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">

        <cfhttpparam type="cookie" name="ASPSESSIONID" value="#ASPSESSIONIDThatYouWereSent#" />

    </cfhttp>

    What matters is that you know the name of the variable that needs to be sent with the token and where it is expected.  All of the exmples above assume that it needs to be sent as a cookie, but if they are expecting it as a formfield or a URL param, then you need to alter the type attribute as needed.

    Hope this helps.

    weezerboyAuthor
    Inspiring
    August 6, 2011

    Mr 12 Robots,

    I'm pretty sure it's a java.

    So this is the code I would need to use

    So how do I find out what this is : JSESSIONIDThatYouWereSentinXML

    Pat

    12Robots
    Participating Frequently
    August 6, 2011

    I thought you said it was sent to you with the XML. I thought you knew that value already.

    It is probably in a cookie sent with the initial HTTP Response.

    Ben's blog post does a really good job of explaining all of this. Are you sure you read it?  http://www.bennadel.com/blog/725-Maintaining-Sessions-Across-Multiple-ColdFusion-CFHttp-Requests.htm

    Here is the function that Ben has in his post to get all of the cookies out of the initial response. It returns a struct with the cookie name as the key. You would just need to then use the JSESSIOND key.

    <code>

    <cffunction name="GetResponseCookies" access="public" returntype="struct" output="false">

    <cfargument name="Response" type="struct" required="true" />

    <cfset var LOCAL = StructNew() />

    <cfset LOCAL.Cookies = StructNew() />

    <cfif NOT StructKeyExists(ARGUMENTS.Response.ResponseHeader,"Set-Cookie")>

    <cfreturn LOCAL.Cookies />

    </cfif>

    <cfset LOCAL.ReturnedCookies = ARGUMENTS.Response.ResponseHeader[ "Set-Cookie" ] />

    <cfloop item="LOCAL.CookieIndex" collection="#LOCAL.ReturnedCookies#">

    <cfset LOCAL.CookieString = LOCAL.ReturnedCookies[ LOCAL.CookieIndex ] />

    <cfloop index="LOCAL.Index" from="1" to="#ListLen( LOCAL.CookieString, ';' )#" step="1">

    <!--- Get the name-value pair. --->

    <cfset LOCAL.Pair = ListGetAt( LOCAL.CookieString, LOCAL.Index, ";") />

    <cfset LOCAL.Name = ListFirst( LOCAL.Pair, "=" ) />

    <cfif (ListLen( LOCAL.Pair, "=" ) GT 1)>

    <cfset LOCAL.Value = ListRest( LOCAL.Pair, "=" ) />

    <cfelse>

    <cfset LOCAL.Value = "" />

    </cfif>

    <cfif (LOCAL.Index EQ 1)>

    <cfset LOCAL.Cookies[ LOCAL.Name ] = StructNew() />

    <cfset LOCAL.Cookie = LOCAL.Cookies[ LOCAL.Name ] />

    <cfset LOCAL.Cookie.Value = LOCAL.Value />

    <cfset LOCAL.Cookie.Attributes = StructNew() />

    <cfelse>

      <cfset LOCAL.Cookie.Attributes[ LOCAL.Name ] = LOCAL.Value />

    </cfif>

    </cfloop>

    </cfloop>

    <cfreturn LOCAL.Cookies />

    </cffunction>

    </code>

    Inspiring
    August 5, 2011

    But partner firm says that wont work...so I stopped pursuing .

    What was their basis for saying it won't work?

    Did you test it locally and demonstrate to yourself that it does work?  (I don't know that it does, but Ben usually knows his stuff and the approach seems sound to me).

    --

    Adam

    weezerboyAuthor
    Inspiring
    August 5, 2011

    The partners have not been very helpful.

    How would I capture the session and then pass it back?

    Patrick Hutchinson

    www.1design.com

    [private information removed]


    Inspiring
    August 5, 2011

    The partners have not been very helpful.


    Well unless they have good grounds for saying what they say, I don't think there's much point in listening to them.

    How would I capture the session and then pass it back?

    Um... I'm confused... isn't that covered very very thoroughly in Ben's blog post?  Or am I misunderstanding you?

    --

    Adam