Go 客户端怎么保存 Cookie 并连续请求接口
Go 客户端要连续访问登录接口和业务接口,关键是复用同一个 http.Client,并给它配置一个 cookiejar.Jar。登录响应里的 Set-Cookie 会由 Client 自动交给 Jar 保存,下一次请求再按 URL 的匹配规则取回 Cookie;不要把响应头里的整段字符串手动复制到下一个请求。
最小可用组合是:一个逻辑会话对应一个 Jar,一个 Client 持有这个 Jar,所有连续请求都使用这个 Client。Jar 默认在内存中工作,不负责把登录态写入磁盘。
http.Client.Jar同时负责接收响应 Cookie 和为后续请求注入匹配 Cookie。- Cookie 是否发送由协议、域名、路径、Secure、过期时间等属性共同决定。
- 多账号或多租户场景不要共用一个 Jar;生产环境建议配置
publicsuffix.List。
先把 cookiejar.Jar 绑定到同一个 http.Client
cookiejar.New(nil) 可以创建一个内存 Cookie Jar。将它放进 Client 的 Jar 字段后,Client 会在发出请求前查找匹配 Cookie,并在收到响应后更新 Jar。下面的地址是示例接口,重点在会话对象的连接方式。
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
)
func main() {
// 一个 Jar 代表一个登录会话,不能在多个账号之间混用。
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
}
client := &http.Client{Jar: jar}
// 登录响应如果包含 Set-Cookie,Client 会自动交给 Jar 保存。
loginBody := strings.NewReader(`{"username":"demo","password":"secret"}`)
loginReq, err := http.NewRequest(http.MethodPost, "https://api.example.test/login", loginBody)
if err != nil {
log.Fatal(err)
}
loginReq.Header.Set("Content-Type", "application/json")
loginResp, err := client.Do(loginReq)
if err != nil {
log.Fatal(err)
}
io.Copy(io.Discard, loginResp.Body)
loginResp.Body.Close()
// 继续使用同一个 Client,业务请求会自动携带可匹配的 Cookie。
profileResp, err := client.Get("https://api.example.test/profile")
if err != nil {
log.Fatal(err)
}
defer profileResp.Body.Close()
fmt.Println(profileResp.Status)
// Cookies 只用于观察某个 URL 当前能取到哪些 Cookie,不是持久化接口。
profileURL, _ := url.Parse("https://api.example.test/profile")
for _, c := range jar.Cookies(profileURL) {
fmt.Println(c.Name, c.Value)
}
}
这里的核心不是调用两次 Get,而是始终保留 client 这个会话容器。若每次请求都写成 &http.Client{},或者登录后换了一个没有同一 Jar 的 Client,后续接口自然看不到登录态。
按域名、路径和协议排查 Cookie 为什么没发送

Jar 不会把所有 Cookie 无条件塞进每个请求。它按照 Cookie 属性和目标 URL 计算“这次能不能带”,因此排查时先把请求 URL 写清楚,再观察 jar.Cookies(u) 的结果。
| 检查项 | 常见现象 | 处理思路 |
|---|---|---|
| Scheme | Cookie 标记了 Secure,但请求使用 HTTP | 改用 HTTPS,或在测试环境明确区分安全与非安全 Cookie |
| Domain | 登录在一个主机,业务请求换了无关域名 | 确认服务端设置的 Domain 与目标主机匹配,不要手动扩大范围 |
| Path | 同域名不同路径的接口拿不到 Cookie | 查看 Set-Cookie 的 Path,接口路径不在范围内时不会发送 |
| 过期时间 | 第一次请求成功,过一段时间后失效 | 检查 Expires 或 Max-Age,并准备重新登录或刷新会话 |
jar.Cookies 返回的是指定 URL 当前可用的 Cookie,适合定位“Jar 里有没有”和“这个 URL 能不能拿到”两类问题。它不是把所有内部状态导出的调试快照;如果 URL 不是 HTTP 或 HTTPS,Cookie 列表也会为空。

为跨子域场景配置 PublicSuffixList
直接传入 nil 作为 Options 对测试很方便,但官方文档明确提示:没有公共后缀列表时,某些域名边界判断会变得不安全。真实服务通常应引入 golang.org/x/net/publicsuffix,让 Jar 能识别 co.uk 这类公共后缀。
# 引入官方 Go 扩展包,让 Cookie Jar 使用公共后缀规则 go get golang.org/x/net/publicsuffix
import (
"log"
"net/http"
"net/http/cookiejar"
"golang.org/x/net/publicsuffix"
)
func newSessionClient() *http.Client {
// 公共后缀列表限制 Cookie 的可设置域边界,生产环境不要省略。
jar, err := cookiejar.New(&cookiejar.Options{
PublicSuffixList: publicsuffix.List,
})
if err != nil {
log.Fatal(err)
}
return &http.Client{Jar: jar}
}
这项配置不会让不同站点共享登录态,作用恰恰是防止服务端越过公共后缀设置过宽的 Cookie。若业务只访问单一主机,它仍然是一个成本很低的安全默认值。
按用户隔离 Jar 并处理内存与并发边界
Client 和符合约定的 CookieJar 可以安全地被多个 goroutine 使用,但“线程安全”不等于“账号隔离”。一个 Jar 里放的是同一逻辑会话的状态;多账号并发时应为每个账号创建独立 Jar 和 Client,避免请求携带错误用户的 Cookie。
另外,cookiejar.Jar 是内存实现,进程重启后登录态不会自动恢复。如果必须跨重启保留会话,需要明确设计持久化 Cookie 的格式、加密和过期清理,并实现自己的 http.CookieJar 或在应用层保存刷新令牌。不要把 Cookie 值直接写入普通日志。
常见问题
为什么登录成功,下一次请求仍然未登录?
最常见原因是换了 Client、没有配置 Jar,或业务 URL 不符合 Cookie 的 Domain、Path、Scheme 与过期条件。先用同一 URL 调用 jar.Cookies 查看匹配结果。
能不能直接复制响应头里的 Set-Cookie?
不建议。手动复制容易带入属性文本、忽略过期和域名规则;让 Client 与 Jar 管理 Cookie 更接近 HTTP 的实际语义。
一个 Cookie Jar 能不能给所有用户共用?
不应该。Jar 可以并发安全地访问,但其中的状态属于会话;多用户服务应按账号、租户或登录上下文隔离。
PHP 同一用户的多个请求为什么排队执行
- 上一篇
- PHP 同一用户的多个请求为什么排队执行
- 下一篇
- Java Optional 的 orElse 为什么每次都执行默认方法
-
- Golang · Go教程 | 24分钟前 |
- Go 怎么边生成数据边上传而不落地临时文件
- 456浏览 收藏
-
- Golang · Go教程 | 37分钟前 |
- Go HTTPS 接口怎么用测试证书完成本地单元测试
- 318浏览 收藏
-
- Golang · Go教程 | 48分钟前 | 文件操作 · Go教程 · 文本处理 · io.MultiReader · Go io.Copy io.MultiReader 文本文件合并 os.Open
- Go 怎么按指定顺序合并多个文本文件
- 120浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go TCP 消息怎么按长度拆包:处理粘包与半包
- 407浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go 大文件怎么流式转换成 Base64
- 394浏览 收藏
-
- Golang · Go教程 | 1小时前 | 结构体 · 切片 · 排序 · Go教程 · Go 多字段排序 结构体切片 slices.SortFunc cmp.Compare
- Go 结构体切片怎么按多个字段排序
- 280浏览 收藏
-
- Golang · Go教程 | 1小时前 | HTTP · 文件上传 · Go教程 · multipart · 文件上传 Go HTTP客户端 mime/multipart multipart.Writer
- Go HTTP 客户端怎么同时上传文件和表单字段
- 489浏览 收藏
-
- Golang · Go教程 | 2小时前 | Excel · csv · Go教程 · 文件编码 · 报表导出 · Excel Go encoding/csv csv.Writer UTF-8 BOM CSV乱码
- Go 导出的 CSV 用 Excel 打开乱码怎么处理
- 124浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Go 中文字符串怎么按字符截取而不产生乱码
- 240浏览 收藏
-
- Golang · Go教程 | 2小时前 | go · 性能测试 · 内存分配 · testing.B allocs/op Go benchmark
- Go benchmark 怎么统计内存分配次数
- 219浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 158次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 87次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 46次使用
-
- PromptHero
- PromptHero是专业的AI提示词搜索引擎与优化平台,支持Stable Diffusion、Midjourney等主流模型。提供海量提示词库、分类搜索、在线课程及社区互动,助力用户高效生成高质量AI图像与文本。
- 26次使用
-
- Stable Diffusion Prompt Book
- 深入解析OpenArt推出的Stable Diffusion Prompt Book,这本免费的开源提示词指南涵盖从基础语法到高级技巧,提供风格化词库与参数建议,助您优化AI绘画生成效果。
- 29次使用
-
- Go语言读取,设置Cookie及设置cookie过期方法详解
- 2022-12-31 137浏览
-
- Go语言中如何确保Cookie数据的安全传输
- 2023-01-07 416浏览
-
- 使用go gin来操作cookie的讲解
- 2023-01-07 142浏览
-
- 浅谈golang的http cookie用法
- 2022-12-31 244浏览
-
- Go error wrapping 实战:别让错误日志只剩一句 failed
- 2026-06-01 151浏览

