Copy link to clipboard
Copied
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???
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>
</Header>
</Response>
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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]
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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>
Copy link to clipboard
Copied
I've got that (JSESSIOND key)..I think
.but how do I pass it back to the other firm.
Copy link to clipboard
Copied
I keep getting "login failed" when I try and cfhttp back to the partner server.
I have attached my code.
Something must be wrong with my cfhhtp tag at the bottom
Copy link to clipboard
Copied
I already told you how to pass it back to the other firm.
I don't see your code.
Copy link to clipboard
Copied
Sorry
Yes you did and I have implemented and it still doesn't work.
Thank you for your help
PAT
Copy link to clipboard
Copied
So you're giving up on this line of help?
If you could post a sample of the HTTP Response (like an image of the dump) and then provide pastebin.com links to your cfhttp calls it might help. Unfortunately, we are only seeing part of the picture.
It would be nice to see,
1. Your initial CFHTTP call code
2. A dump of the response from that call
3. The method you are using to get the cookies out of that reposne
4. The CFHTTP code that you make after that
If I am understanding you correctly, you are making 2 requests. And you should be getting 2 responses. Here is how I understand how it should work
1. You make a CFHTTP call to the partner
2. You get the response form that call in a variable (defined in the "result" attribute of the prior CFHTTP call. So if you said result="response" then the response would be in a variable called "response".
3. You take the data from the filecontent key of the response (So in my example that would be response.filecontent)
4. You then need to get the cookies out of the response. That is what the Nadel function that I posted before is for. You pass in the whole response and get back a struct with the cookies. So it might look like this: <cfset respCookies = GetResponseCookies(response) />
5. You do something with the XML and then post it back to the partner firm with a second CFHTTP request, like this:
<cfhttp url="https://partnerfirm.com" method="post">
<cfhttpparam type="xml" name="XMLUpload" value="#xml_validated#">
<cfhttpparam type="cookie" name="JSESSIONID" value="#respCookies.JSESSIONID#" />
</cfhttp>
The JSESSIONID should ONLY be included in requests AFTER the initial response. If you are including it in your first HTTP call, then you are likely doing it wrong. Before the first call a session has not yet been established.
I really want to help. This should be a relatively simple task if these are, in fact, just HTTP sessions we are dealing with. But without seeing an example of the initial response, I cannot know.
Copy link to clipboard
Copied
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
<cfset valuesArray = elementsArray
<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>
Copy link to clipboard
Copied
ok, so perhaps we have been tackling this wrong from the start. The token to maintain the session is not in the HTTP header, it is in the HTTP body embedded in the XML. Is that correct? If so, then this is probably not an HTTP session at all, it is some other session being maintained by the calling server. Perhaps you need to be embedding the token back in the XMl the same way that it came to you.
Since you did not provide an example of how it is sent to you I am just going to guess, but perhaps you simply need to send
<Response>
<Header>
<Status>1</Status>
</Header>
<Token>#tokenfrompartnerfirm#</Token>
</Response>
Have you tried that? I would say that it probably needs to be passed back in the same structure in which it arrived. All of this is hard to say without an example and without documentation of how it should work.
Also, right now, it does not look like you are even using the Nadel function and, if I am guessing correctly about it not being an HTTP session, then you do not need it.
Copy link to clipboard
Copied
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>
</Header>
</Response>
Copy link to clipboard
Copied
Thank you so much for your help.
I couldnt have done this without it.
Its incredible what you know.
Copy link to clipboard
Copied
Glad it worked out. One thing to keep in mind for the future, we probably would have solved this within the first post or two if we had all the information upfront. We had a misunderstanding on what type of session you were talking about from the very start.
I'm glad I could help. It really ended up being a simple solution. Those are the best kinds.