Patrick
Patrick

Reputation: 2577

ColdFusion not maintaining session across cfhttp calls

I'm having an issue trying to use cfhttp. I'm using an API that requires me to send login credentials, then send subsequent commands. The reply on the subsequent commands is "login required". After looking at my requests, I think I've found the issue but I don't understand it.

Here's my login call:

<cfhttp url="#Target#"  result="LoginAttempt"  method="POST" REDIRECT="No" useragent="#strUserAgent#"> 
    <cfhttpparam type="FORMFIELD" name="action" value="Login"  />
    <cfhttpparam name="loginUsername" value="#Username#" type="FORMFIELD" />    
    <cfhttpparam name="loginPassword" value="#Password#" type="FORMFIELD" /> 
</cfhttp> 

When this returns 200 OK, I set the cookie to use for future calls:

<cfset ThisCookie = LoginAttempt.responseHeader["Set-Cookie"] />

Then, proceeding with the next call:

<cfhttp url="#Target#"  result="CreateTransactionAttempt" method="POST" REDIRECT="No" useragent="#strUserAgent#"> 
    <cfhttpparam type="header" name="Cookie" value="#ThisCookie#" />
    <cfhttpparam type="FORMFIELD" name="action" value="CreateTransaction" />
    <cfhttpparam type="FORMFIELD" name="transactionName" value="#TransactionName#" />
</cfhttp> 

The problem I think is this; when I look at the header of the second cfhttp call, it doesn't match the cookie provided by the first call. I'm not sure why this would be. On Ben Nadel's blog page here, he has a function that splits the returned cookie into a struct and passes that into the second call. I've tried that with the same result. Am I missing something?

Upvotes: 2

Views: 337

Answers (2)

Mark Moran
Mark Moran

Reputation: 13

While researching this same problem I came across CFHTTPSession.cfc by Ben Nadel that deals with the cookies for you.

Upvotes: 0

Alex
Alex

Reputation: 7833

You cannot take the Set-Cookie header from the response and just echo it as Cookie header in the request. Set-Cookie can contain directives like Domain, Path, Secure, HttpOnly, Expires, Max-Age etc. You need to strip them and reduce it to the cookie's key-value pair, because that's what the Cookie header in your request is supposed to contain.

Example 1, single cookie

Response:

Set-Header: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D; Path=/; HttpOnly

Key-Value-Pair:

Key: JSESSIONID
Val: 9335968036E8B5EE9F9D00032A5A665D

Request:

Cookie: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D

Example 2, multiple cookies

Response:

Set-Header: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D; Path=/; HttpOnly
Set-Header: uid=d1b68f6fe0ca70e8d53bd3a2f32d06c1f1554317436; expires=Thu, 02-Apr-20 18:50:36 GMT; path=/; domain=.example.org; HttpOnly

Key-Value-Pairs:

Key: JSESSIONID
Val: 9335968036E8B5EE9F9D00032A5A665D

Key: uid
Val: d1b68f6fe0ca70e8d53bd3a2f32d06c1f1554317436

Request:

Cookie: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D; uid=d1b68f6fe0ca70e8d53bd3a2f32d06c1f1554317436

For starters, something naive like:

<cfset ThisCookie = getToken(LoginAttempt.responseHeader["Set-Cookie"], 1, ";") />

could possibly already solve the problem for you.

Upvotes: 10

Related Questions