Solved

ColdFusion and RETS

Posted on 2013-11-26
17
1,015 Views
Last Modified: 2016-02-26
Hi All,

I am trying to get into the RETS system using ColdFusion.

http://rets.mlxinnovia.com/help/index.php
www.reso.org

At this point I have been able to send a login request using the following code:

<cffunction name="getAuthenticated" access="public" returntype="any">
     
<cfargument name="userName" type="string" required="yes">
<cfargument name="password" type="string" required="yes">

<!--- First request to get Authenticate Information --->
<cfhttp url="http://rets.offutt-innovia.com:8080/nne/login?rets-version=rets/3.0" method="get" username="#ARGUMENTS.userName#" password="#ARGUMENTS.password#">

<cfhttpparam name="Accept" type="header" value="text/xml,text/plain;q=0.5">
<cfhttpparam name="User-Agent" type="header" value="wsdl">
<cfhttpparam name="RETS-Version" type="header" value="3.0">
</cfhttp>
			
<cfset tempCookie = cfhttp.Responseheader["Set-Cookie"]>
			
<cfreturn tempCookie>
			
</cffunction>

<cfcookie name="JSESSIONID" value="#getAuthenticated('myusername','mypassword')#" expires="never">

<cfdump var = "#JSESSIONID#">

Open in new window


When I run the file I get the following response:

JSESSIONID=D95AC85438EBBB3B8FC07375ED157AAE; Path=/nne/; HttpOnly


So I have the request authenticated, but being a SOAP based system - I have no clue how to continue passing the authentication back and forth to the site to make calls to their system.

I truly have no understanding of SOAP or using stateless requests like this.  I only got the code above to work because I found it on another support ticket.

My first attempt was to place the following after the initial code:

<cfhttp url="http://rets.offutt-innovia.com:8080/nne/getmetadata?Type=METADATA-TABLE&ID=Property:ResidentialProperty" method="get" >
</cfhttp>
<cfdump var="#cfhttp#" />

Open in new window


And I get back great big 401 Unauthorized response code.  If I dump the initial function cfhttp - I get a status code  200 OK

Can anyone help me get to the next step of being able to use the login authentication to start making requests on the system?  

I am looking for actual code help as well as theory and understanding.  However I learn the best from code samples.   I like to pull things apart and see how they work then put them together again :)

For reasons too long to go into - I am on a 15 day time crunch to get this done.  As always - help is greatly appreciated.

God Bless,
Chris
0
Comment
Question by:luksha
  • 9
  • 8
17 Comments
 
LVL 52

Expert Comment

by:_agx_
ID: 39678656
(no points...just a brief comment)

Edit:   Sorry I'm working on a deadline myself and obviously I didn't fully read your question :/ Apologies I don't have time for a fuller response but ...

> <cfcookie name="JSESSIONID"
> value="#getAuthenticated('myusername','mypassword')#" expires="never">

Actually that just sets a cookie in your browser, it has no effect on the cfhttp call. Since cfhttp is sort of like a mini-browser, you need use <cfhttparam type="cookie"  ...> to set a cookie for the cfhttp request.
0
 

Author Comment

by:luksha
ID: 39678952
Thanks AGX.  I will did a little deeper for the response needed. I am trying to learn how to interpret the RETS documentation on how to send the credentials back.

Digest authentication is brand new to me after being away from CF coding for two years.  It whipping me like a post.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39679322
I know the feeling ;-)  Since I don't have the time to delve into it now, take this with a large grain of salt ... but the impression I got from the other thread was that the first http request (w/user and password) gets you the authentication cookie.

You then need to parse out the cookie value and include it as a header when making subsequent cfhttp requests.

           ...
          <cfhttpparam name="JSESSIONID" value="D95AC85438EBBB3B8FC07375ED157AAE">

You can find a more detailed explanation of maintaining sessions w/cfhttp here:
http://www.bennadel.com/blog/725-Maintaining-Sessions-Across-Multiple-ColdFusion-CFHttp-Requests.htm
0
 

Author Comment

by:luksha
ID: 39679462
Thanks for the link.  I have had been reading that article all this afternoon and finally got to pulling the JSESSIONID.  I am thinking now that my issue is with returning that value.  For whatever reason I cannot figure out how to send it back to the RETS system in such a way that it actually keeps me logged in.

Here is my new function: (only slightly modified)
<cffunction name="getAuthenticated" access="public" returntype="any">
<cfargument name="userName" type="string" required="yes">
<cfargument name="password" type="string" required="yes">

<!--- First request to get Authenticate Information --->
<cfhttp url="http://rets.offutt-innovia.com:8080/nne/login" method="get" username="#ARGUMENTS.userName#" password="#ARGUMENTS.password#">
<cfhttpparam name="Accept" type="header" value="text/xml,text/plain;q=0.5">
<cfhttpparam name="User-Agent" type="header" value="#CGI.HTTP_USER_AGENT#">
<cfhttpparam name="RETS-Version" type="header" value="RETS/1.8.0">
</cfhttp>
<cfreturn cfhttp>
</cffunction>

<cfset head = "#getAuthenticated('myuser','mypass')#">

<cfset list1 = head.Responseheader["Set-Cookie"]>

<cfset jsess = trim(replace(listgetat(list1,1,';'),"JSESSIONID=",''))>

JSESSIONID: <cfoutput>#jsess#</cfoutput> 

<cfhttp url="http://rets.offutt-innovia.com:8080/nne/getmetadata?Type=METADATA-TABLE&ID=Property:ResidentialProperty" method="get" >
<cfhttpparam name="JSESSIONID" type="header" value="#jsess#">
</cfhttp>

<cfdump var="#cfhttp#">

Open in new window

From that I get the following output:

JSESSIONID: FAB7959B2BB9239F2423F5276678A62E   

HTTP/1.1 401 Unauthorized Connection: close Date: Tue, 26 Nov 2013 23:16:04 GMT Server: Apache/2.2.3 (Red Hat) Content-Length: 951 RETS-Session-ID: FF71A2FF5AFD9BA964574FB771976369 Cache-Control: private Set-Cookie: JSESSIONID=FF71A2FF5AFD9BA964574FB771976369; Path=/nne/; HttpOnly WWW-Authenticate: Digest realm="rets.offutt-innovia.com",nonce="4ebfc80c52176b73d377fedc59134912",opaque="6d6819542f9bda84914a790a98d7ca03",qop="auth" Content-Type: text/html;charset=utf-8 RETS-Server: RETSInnoVia/3.0 

Open in new window

Note that the JSESSIONIDthat is output from the login is different from both the RETS-SESSION-ID and the JSESSIONIDshown in the error.

I have tried sending both:
<cfhttpparam name="RETS-Session-ID" type="header" value="#jsess#">
and 
<cfhttpparam name="JSESSIONID" type="header" value="#jsess#">

Open in new window


I can't figure out how come the session id is not persistent?

Thanks for your popping in AGX I am grateful for the direction.  I am SLOWLY learning a little more about this part of CF but for some reason it is not coming easy anymore ;)

I will keep plugging away and I hope you will keep thinking as well.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39679505
(Edit)

> <cfhttpparam name="JSESSIONID" type="header" value="#jsess#">

Try sending it as cfhttpparam type=cookie, rather than type="header". (Technically a cookie IS a sort of header, but there's definitely a distinction in how they're processed.)
0
 

Author Comment

by:luksha
ID: 39679559
Thanks for that heads up.   I completely forgot to send it as a cookie.  I had that earlier and then pasted some other code and missed it.  

Unfortunately it still did not work.   What I found while reading the docs some more is this wonky explanation that I haven't figured out yet that says to send the 'Authorization'

So if I send this:
<cfhttpparam name="Authorization" type="header" value="#jsess#">

in my second call, I get a status code 200 (ok) however I receive no data back in xml or otherwise.  Also the system seems to have set a new JSESSIONID.  

I have even tried just manually setting the JSESSIONID  (cfset cookie.JSESSIONID = jsess) to no avail.  The headache I woke up with is slowly growing :)

I think it is time for me to call it quits for an hour and get some caffeine!
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39679768
After briefly looking at the "specifications" I can see why you have a headache. (Coincidentally I'm working on something completely different .. yet the documentation is equally cryptic. "Advil anyone?" ;-)

Anyway, are you including the user-agent, version, etc... headers in the 2nd request? I happened to notice section 3.3 Required Client Request Header Fields mentioned something about them being required.  I don't know if it'll make a difference, but it couldn't hurt to include them.
0
 

Author Comment

by:luksha
ID: 39679926
Ok so I had a little fun trying to get a couple pages for you to see what I have tried.  I have to admit that making these 4 pages was the most fun of this project so far - because I saw an end in sight :)

http://tiegerrealty.com/rets/

There are four index pages.  Each of them login via a cffunction, then attempt to pull metadata from the system.  The metadata they are pulling is using the following url format (which works directly in the browser once I enter in the username and password when prompted)

http://rets.offutt-innovia.com:8080/nne//getmetadata?Type=METADATA-TABLE&ID=Property:ResidentialProperty

Who knows - maybe you will say 'oh dummy you can't do that in one page, you need to first do this, then you can do that'  

Thanks again!
Chris
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 52

Expert Comment

by:_agx_
ID: 39681284
Nice! You know ... I see an error in the 1st response dump, suggesting there's a problem from the very beginning

  <RETS ReplyCode="20036" ReplyText="Missing or Invalid RETS Version" > </RETS>

> works directly in the browser

That's might be a good thing.  I suspect the cfhttp call is missing some headers or sending the wrong values.  If you use FireFox, there's a neat plugin that could help. It's called "Live HTTP Headers".  I'd recommend installing it, then loading the page(s) in your browser. The plugin will let you see what headers your browser passes to the RETS server and hopefully we can see what's different/missing from the cfhttp calls.

https://addons.mozilla.org/en-US/firefox/addon/live-http-headers/
0
 

Author Comment

by:luksha
ID: 39681402
Thank you for the plugin - I am installing now.  I have seen that error each time as well, which is the main reason I made that page allow you to change the RETS version.  I have tried all the version numbers they state on their website.  Everyone returns the same error.

I am excited for the plugin and will let you know asap!

Thanks so much,
Chris
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39681474
Btw, just to be clear, I mean load the regular urls's in your browser ie

http://rets.offutt-innovia.com:8080/nne//getmetadata?Type=METADATA-TABLE&ID=Property:ResidentialProperty

... enter the credentials, and check the Live HTTP Headers results
0
 

Author Comment

by:luksha
ID: 39681522
Yeah, that's what I did,  I am more confused than ever.  Here is a shot of the headers from the working url call...

RETS Live url feed headers - working
I tried to hire someone on odesk to do this for me and they wanted $400 to work through this.  I am starting to wonder if I shouldn't have just let them. :)
0
 
LVL 52

Accepted Solution

by:
_agx_ earned 500 total points
ID: 39681726
(Edit)

First, is that the only request shown? Did you check "Show -> Redirects" on the Generator tab? I think there might be a request/response before the one above. ie From the login

Yeah, the RETS stuff is a little complicated .. made worse by the poor documentation.  Side note, I saw a very promising blog series about it yesterday. A little old but it looked like it covered everything you're trying to do.. unfortunately ALL the links to the code are broken and not even archived on waybackmachine.org :/

Anyway, it looks like you're back to the whole digest authentication stuff, which cfhttp doesn't support. Truthfully I haven't read through the specs fully (It seems like there's different ways to authenticate ... ?). But I saw something similar in 4.1.x Client Authentication.


The first time the client requests the document, no Authorization header is sent, so the server responds with:

       HTTP/1.1 401 Unauthorized
       WWW-Authenticate: Digest realm="Users@example.com",
       nonce="dcd98b7102dd2f0e8b11d0f600bfb0c0"
       opaque="5ccdef346870ab04ddfe0412367fccba"

The client may prompt the user for the username and password, after which it will respond with a new request, including the following he client may prompt the user for the username and password, after which it will respond with a new request, including the following Authorization header:

      Authorization: Digest username="joesmith",
      realm="Users@example.com",
      nonce="dcd98b7102dd2f0e8b11d0f600bfb0c0",
      opaque="5ccdef346870ab04ddfe0412367fccba",
      uri="/login",
      response="13258d9b0bc217c9502b47e32dff8ee9"


... which looks like the info in your screen shot.  The thing I'm not sure about is if you can use that to construct the necessary headers for cfhttp or if you have to use an external library to handle the whole digest authentication stuff. BUT ... I found this thread on Tek-Tips which seems like it generates the necessary Authentication header.  Can you give it a try?

http://www.tek-tips.com/viewthread.cfm?qid=1373438
0
 

Author Comment

by:luksha
ID: 39681804
Thank you AGX.

You are much quicker at finding those articles than I ma that's for sure.  I spent hours over the last couple days reading articles like the ones you listed above.  (including the one with all the missing code.) I wasn't sure about the whole CF doesn't do digest authentication thing though. I was hoping....

But my hopes are finally dashed.  As for the Show -> Redirects I had checked that in the beginning, but noticed that once I close the options - the settings are reset to default.  I was able to leave the console open and open a new FF window and see some of the response headers.  It is overwhelming.

After talking to the client, it looks like I am going to recode the website to the RETS system using a paid SaS for updates instead of a direct RETS connection from our own website.  I found this site yesterday http://retscloud.com/ that will do the transfer for $15 / month.

It looks very promising and I just need to stick with the code I am familiar with at this point and get the site running well.

AGX  You have been an amazing help and I hate to stop going down this road right now - but unfortunately I need to do what the client is willing to take on.  I will probably pursue this in the future but maybe when my server upgrades the CF server it will use Direct Authentication :)

Thank you so much for all your help!

God Bless and Happy Thanks giving (If you're here in the US and celebrate it)

Chris
0
 

Author Closing Comment

by:luksha
ID: 39681812
You were such a great help through this whole thing.  I am only sorry that in the end I had to give up the hunt for now.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39681892
I completely understand. If I had more time to devote to it, I'm sure we could figure it out .. but it sounds like that's a luxury neither one of us has right now :)

Sorry I couldn't be of more help on this one. Hope you have a great Thanksgiving too !
0
 
LVL 52

Expert Comment

by:_agx_
ID: 39682353
BTW, I appreciate the points, but since ultimately we didn't manage to find a solution to the original problem, it makes more sense to delete this thread.

Best of luck with the new service you found! Sounds like it'll make things a lot easier.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

PROBLEM: How to add your own buttons to the bottom toolbar with paging info ( result count ). While creating a cfgrid, I ran into an issue where I wanted to embed my own custom buttons where the default ones ( insert / delete / etc… ) are for aes…
Recently while working on a project I got a very annoying cfdocument has no body error message. I had never seen this error before. So I checked the code. The code was pretty simple; it was Just showing me the cfdocumnt tag and inside that tag a …
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now