Go cookiejar 怎样让测试客户端保持会话 Cookie
给测试用的 http.Client 设置非空 Jar,再让同一用户的请求复用这个客户端,就能自动接收响应里的 Cookie,并在匹配的后续请求中携带。我的选择是把“客户端与独立 Jar”作为一个测试用户的整体,而不是在每次请求中手工拼 Cookie。
官方文档:https://pkg.go.dev/net/http/cookiejar;客户端接口:https://pkg.go.dev/net/http#Client。
先把 Cookie 状态绑定到客户端
这里需要的能力是状态容器,不是浏览器窗口。Jar 保存 Cookie;http.Client 将它绑定到请求和响应。Jar 为空时,Client 不会自动记住服务器下发的 Cookie,只发送请求上显式设置的值。直接调用包级 http.Get 也不会自动使用你另建的客户端。
本例的六个对象分属三个边界:测试用户包含 Client、Jar;HTTP 数据包含 Set-Cookie、Cookie;测试服务包含 /session、/profile。接口负责串起它们,连接复用与会话存储则是两回事。

用一个完整测试表达会话约定
将下面代码保存为已有 Go 模块中的 session_test.go,并将 golang.org/x/net/publicsuffix 加入模块依赖;依赖版本应与项目工具链要求相容。它属于 golang.org/x/net 模块,不是标准库包。此处给出可复用的测试写法,不附本机运行记录。
package session_test
import (
"io"
"net/http"
"net/http/cookiejar"
"net/http/httptest"
"testing"
"time"
"golang.org/x/net/publicsuffix"
)
func TestClientKeepsSession(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session", func(w http.ResponseWriter, r *http.Request) {
// 只提供测试会话标记,不代表真实认证或密码校验。
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
http.SetCookie(w, &http.Cookie{
Name: "session", Value: "test-user",
Path: "/", HttpOnly: true,
})
w.WriteHeader(http.StatusNoContent)
})
mux.HandleFunc("/profile", func(w http.ResponseWriter, r *http.Request) {
// 后续请求必须携带预期标记,才能通过测试约定。
c, err := r.Cookie("session")
if err != nil || c.Value != "test-user" {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusNoContent)
})
server := httptest.NewServer(mux)
t.Cleanup(server.Close)
jar, err := cookiejar.New(&cookiejar.Options{
PublicSuffixList: publicsuffix.List,
})
if err != nil {
t.Fatal(err)
}
client := &http.Client{Jar: jar, Timeout: 3 * time.Second}
t.Cleanup(client.CloseIdleConnections)
// 读取并关闭每个响应体;不要把 defer 堆积在请求循环里。
requestStatus := func(method, path string) int {
t.Helper()
req, err := http.NewRequest(method, server.URL+path, nil)
if err != nil {
t.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
_, readErr := io.Copy(io.Discard, resp.Body)
closeErr := resp.Body.Close()
if readErr != nil {
t.Fatal(readErr)
}
if closeErr != nil {
t.Fatal(closeErr)
}
return resp.StatusCode
}
if got := requestStatus(http.MethodGet, "/profile"); got != http.StatusUnauthorized {
t.Fatalf("会话建立前状态码=%d", got)
}
if got := requestStatus(http.MethodPost, "/session"); got != http.StatusNoContent {
t.Fatalf("设置会话状态码=%d", got)
}
if got := requestStatus(http.MethodGet, "/profile"); got != http.StatusNoContent {
t.Fatalf("保持会话后状态码=%d", got)
}
}
测试约定是:没有会话时访问资料接口得到401;POST建立标记得到204;再次访问资料接口得到204。这里刻意不手工复制响应 Cookie,才能让最后一个断言覆盖 Jar 与 Client 的绑定。若每次请求都新建 Jar,最后的请求没有此前的状态。
测试服务使用普通 HTTP,因此示例没有设置 Secure;这只是隔离测试的传输选择。它的固定值也只用于说明客户端保存能力,不能拿来充当实际用户凭据。
公共后缀列表决定域名边界
cookiejar.New(nil) 可以创建 Jar,但没有公共后缀保护。需要接触真实域名的客户端,我会显式传入 publicsuffix.List。官方包地址:https://pkg.go.dev/golang.org/x/net/publicsuffix。
公共后缀不等于简单取最后一个域名片段:例如 co.uk 本身就是公共后缀。列表帮助 Jar 约束服务器能设置的域范围;它不负责登录、不替应用授权,也不自动让任意子域共享会话。该包提供编译进依赖版本的数据快照,更新依赖才会更新快照。
从配置角度看,三个边界是“创建配置”(Options、PublicSuffixList)、“规则依赖”(publicsuffix.List、公共后缀数据)、“状态容器”(Jar、Domain)。Options 关联 PublicSuffixList 和 Jar,PublicSuffixList 关联实现,实现关联数据;Jar 对 Domain 的处理受这些规则约束。

保持会话时容易忽略的限制
| 现象 | 优先检查 | 调整方向 |
|---|---|---|
| 设置接口成功,后续仍是401 | 是否复用了同一Jar | 让同一测试用户复用带Jar的Client |
| 换路径就没有Cookie | Cookie的Path范围 | 按接口实际范围设置;示例明确使用/ |
| 换主机名后丢失会话 | 实际URL主机与Domain | 不要混用localhost和127.0.0.1 |
| 不同用户相互影响 | 是否共享了Jar | 每个用户分别创建Jar |
| HTTP请求不带Secure Cookie | URL协议 | 需要该属性的测试使用HTTPS服务 |
共享连接池不等于共享用户身份;Cookie 也不按端口隔离,因此给两个测试服务分配不同端口,不足以保证共享 Jar 时的用户隔离。对于重定向,Client 会为它跟随的每个目标咨询 Jar;不能把一次登录理解为对所有目标都发送同一份头。
这套内存 Jar 不会自动保存到磁盘,也不是完整浏览器环境。若需求是浏览器脚本、跨站上下文或页面策略行为,应在对应浏览器环境中另外测试。本文只覆盖 HTTP 客户端会话 Cookie。
常见问题
只调用 Request.AddCookie 可以吗?
可以给单次请求添加值,但服务器更新 Cookie 后,手工方式还要自行同步。要表达连续会话,我更愿意把状态交给 Jar。
HttpOnly 会阻止Go客户端发送Cookie吗?
不会。它主要限制浏览器脚本访问,不能用来解释这里的请求为何缺少Cookie。
同一个客户端适合多个测试用户吗?
同一Jar意味着共享会话容器。需要独立身份时,创建各自的Client与Jar;可以根据测试设计另行考虑底层Transport的复用。
Go cmplx.Rect 怎样把幅值和相位转换成复数
- 上一篇
- Go cmplx.Rect 怎样把幅值和相位转换成复数
- 下一篇
- Go cmplx.Conj 怎样计算复数的共轭值
-
- Golang · Go教程 | 30分钟前 |
- Go cmplx.Rect 怎样把幅值和相位转换成复数
- 331浏览 收藏
-
- Golang · Go教程 | 45分钟前 | Go 模糊测试 fuzz testing.F.Skip testing.T.Skip
- Go testing.F.Skip 怎样跳过不适用的模糊测试输入
- 288浏览 收藏
-
- Golang · Go教程 | 48分钟前 |
- Go os.File.Truncate 怎样调整文件长度并处理偏移
- 239浏览 收藏
-
- Golang · Go教程 | 51分钟前 |
- Go database/sql 怎样理解事务提交时的 context 取消
- 138浏览 收藏
-
- Golang · Go教程 | 54分钟前 |
- Go database/sql ColumnType.DecimalSize 怎样读取 DECIMAL 精度和小数位
- 115浏览 收藏
-
- Golang · Go教程 | 56分钟前 |
- Go os.File.Chown 怎样修改文件所有者并处理平台差异
- 239浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go path.Match 怎样匹配带反斜杠的文件模式
- 414浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go go/version.IsValid 怎样判断版本字符串能否解析
- 189浏览 收藏
-
- Golang · Go教程 | 1小时前 | 文件操作 · go · Go 临时文件 os.OpenFile O_EXCL O_CREATE
- Go os.OpenFile 怎样原子创建不覆盖的临时文件
- 155浏览 收藏
-
- Golang · Go教程 | 1小时前 | 标准库 · 定时器 · 并发控制 · Go教程 · 工程实践 · Go 延迟任务 time.Timer Timer.Stop 并发清理 time.AfterFunc
- Go time.AfterFunc 怎样避免重复调度清理任务
- 475浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go crypto.Hash.New 怎样为已注册哈希算法创建摘要器
- 233浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go encoding/binary.Read 怎样解码固定布局的二进制结构
- 460浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 1043次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 1041次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1195次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1143次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 989次使用
-
- Go map 并发写 panic 怎么办:从共享 map 到可控写入路径
- 2026-06-30 123浏览
-
- 详解Go 语言如何通过测试保证质量
- 2022-12-29 290浏览
-
- Golang 单元测试和基准测试实例详解
- 2022-12-23 275浏览
-
- GoLang基础学习之go test测试
- 2023-01-01 265浏览
-
- Golang实现HTTP编程请求和响应
- 2022-12-28 101浏览

