Sometimes when using external APIs it’s necessary to store returned cookies, for example if a cookie is being used for authentication.
There are two sides to this coin, saving the cookie, and then sending it again on subsequent requests. cURL offers options for this, --cookie-jar
(or -c
) to save cookies, and --cookie
(or -b
) to send cookies back again.
Let’s imagine that you’re performing authentication by posting data to an API. Your cURL options might look something like this, assuming that the data to be sent is stored in the local variable $data.
// the authentication data we wish to send
"-d @$data " &
// set the Content type header to JSON
"--header Content-Type:application/json " &
// create a cookie jar to store cookies in
"--cookie-jar $$CookieJar "
You’ll see that the last options being set is --cookie
, and the returned cookie data is being saved into global variable $$CookieJar
.
Here’s an example of what we end up with in that global variable
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
api.msdev.co.uk FALSE / FALSE 0 PHPSESSID 04oj6mj6hglq0t8iibkmql0u71
You can see that a lot of it’s ‘header’ information, but then the last line is an actual cookie value which has been returned. It amuses me that in 2017 the format of the file still confirms to a Netscape specification from 1994 (hands up if you’re old enough to remember Netscape Navigator)
As an aside, the values in that row are tab separated, and relate to
- the server the cookie is from (api.msdev.co.uk)
- can sub-domains of the domain access the cookie (FALSE)
- the path on the server the cookie is valid for (‘/’ i.e. everywhere)
- is https required to use this cookie (FALSE)
- when the cookie expires (0 means ‘at the end of the session’, any other number is a Unix timestamp)
- the name of the cookie (PHPSESSID)
- the cookie value (04oj6mj6hglq0t8iibkmql0u71)
All good! Now when we want to make a subsequent call to that server we need to send the content of the $$CookieJar back again. Unfortunately it’s not quite as simple as it might seem – we need to do a little manipulation of that variable – like this:
Set Variable [ $CookieString ; Value : Substitute ( $$CookieJar ; "¶" ; Char(10) ) ]
What we’re doing here is replacing the paragraph breaks in the global variable with a ‘line feed’ character – this allows the resulting variable to sent as a string. For our subsequent call, we then add that to the cURL options:
// for debugging ONLY set error reporting on
"--show-error " &
"--dump-header $$Headers " &
// set the Contet type header to JSON
"--header Content-Type:application/json " &
// send the cookies with the request
"--cookie $CookieString"
It’s important to note that you need to place the variable name inside the double quotes as in the example above – if you think you can be clever and skip using the local variable and just do
// send the cookies with the request
"--cookie " & Substitute ( $$CookieJar ; "¶" ; Char(10) )
then be prepared for disappointment and frustration!
If you’re going to be at DevCon this year, then come and see my Explore cURL for FileMaker session on Tuesday at 1415 where I’ll remind you of this important ‘gotcha’ and show you lots more magic that we now have access to through cURL options.
Thank you for your writing about “The Cookie Jar”. It’s help my work is done.
September 24, 2021 at 9:08 amThank you very much.