Example: HTTP Client Manage Cookies
Use http.CookieJar when an HTTP client needs to keep cookie state across requests.
Cookies are commonly used for login sessions, authentication state, preferences, and shopping carts.
For automatic cookie handling, use a CookieJar. When the application needs to send one specific cookie, use Request.AddCookie.
Use a Cookie Jar
If a server sets a session cookie, an http.Client with a cookie jar can store it and send it on later matching requests.
If the first response contains:
the jar stores the cookie. The second request can then include:
The important part is that both requests use the same client and therefore the same jar.
The first response body is closed immediately because it is no longer needed. Deferring both closes until the function returns would keep the first response body open unnecessarily.
The standard cookiejar stores cookies in memory. publicsuffix.List provides the public suffix information used when evaluating cookie domains.
golang.org/x/net/publicsuffix is an external package, not part of the standard library.
For a short example, panic keeps the setup compact. Production code should return or handle errors.
Keep Cookie State Isolated
A cookie jar is client state. Its ownership should follow the session it represents.
For two independent sessions:
The standard cookiejar.Jar is safe for concurrent use, but that does not make shared authentication state safe.
Do not use one jar for unrelated users:
if requests from different users use that client.
A better boundary is:
The transport can be reused for connection pooling; cookie state should remain isolated by session.
For a login flow, reuse the same client:
If the login response sets a session cookie, the second request can use it automatically.
Add or Inspect Cookies Manually
Use Request.AddCookie when the application deliberately controls which cookie to send:
This is useful when the application already has a session value and does not need a cookie jar to maintain session state.
Prefer:
over manually constructing:
Do not copy Set-Cookie directly into Cookie:
Set-Cookie is a response header; Cookie is a request header. They have different formats and semantics.
Read Cookies from a Response
When the application needs to inspect cookies explicitly:
If a cookie jar is configured, normally there is no reason to extract a cookie just to attach it to the next request.
Inspect Cookies in the Jar
jar.Cookies returns the cookies currently applicable to a particular URL:
This is useful when debugging authentication problems.
It is not a dump of every cookie the jar has ever received. The result depends on the target URL and cookie attributes.
How Cookie Matching Works
A cookie is more than a name and value. The jar uses attributes such as:
DomainPathExpiresMax-AgeSecure
to determine whether a cookie applies to a request.
For example:
can apply to:
but not:
A Secure cookie is only sent over HTTPS.
A cookie can also be restricted by domain. Do not assume that a cookie received from one host will automatically be sent to every related host.
Expiration also matters:
or:
The jar removes expired cookies from consideration.
Redirects
http.Client consults the jar for each request it makes while following redirects.
For example:
The cookie is not simply copied from request A to request B. The new URL determines which cookies apply.
This matters when a redirect changes the host, path, or scheme.
Browser-Only Behavior
A Go HTTP client is not a browser.
net/http does not execute JavaScript, provide a DOM, or have browser page/navigation context.
The cookie jar handles HTTP cookie matching, but browser policies such as SameSite are not enforced in the same way because a Go client does not have the browser navigation context those policies depend on.
Likewise, HttpOnly is primarily a browser-side restriction on script access. It does not prevent Go code from inspecting a cookie received in an HTTP response.
Common Failures
Login succeeds, but the next request is unauthenticated
Usually check:
- Both requests use the same client and jar.
- The cookie has not expired.
- The request URL matches the cookie's domain and path.
- HTTPS is used when the cookie is
Secure. - A redirect did not move the request outside the cookie's scope.
Cookies disappear after restart
The standard cookiejar.Jar is in-memory.
If cookie state must survive a process restart, use an explicit persistent store such as a database or external session store.
Do not assume that cookiejar.New provides browser-style persistent cookies.
A new client loses the login session
This loses the jar state:
If the requests belong to the same session, keep using the same client and jar.
One client is used for multiple users
This is dangerous when the client owns user-specific authentication cookies.
Keep the cookie jar aligned with the session or user identity.
Production Notes
Every production request needs an explicit timeout or cancellation policy.
http.Client.Timeout is one option:
A request context is another when the caller needs to control the request lifetime.
Do not log authentication cookie values:
and do not put them into logs, traces, spans, metrics labels, or error messages.
For long-running loops, close response bodies as soon as each response is no longer needed instead of accumulating deferred closes until the outer function returns.
Finally, remember the two ownership boundaries:
- Transport → connection reuse
- CookieJar → session state
Reuse transports when appropriate, but do not share user-specific cookie state accidentally.