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?
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.
Response:
Set-Header: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D; Path=/; HttpOnly
Key-Value-Pair:
Key: JSESSIONID
Val: 9335968036E8B5EE9F9D00032A5A665D
Request:
Cookie: JSESSIONID=9335968036E8B5EE9F9D00032A5A665D
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.