登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  Golang >  Go教程

Go http.Cookie 怎么设置 SameSite 和 Secure 属性

来源:17golang原创

时间:2026-09-08 08:58:18 430浏览 收藏

在 Go 服务里设置登录态 Cookie,关键不是把属性拼成一长串字符串,而是正确填写 http.Cookie。通常可以从 SameSite 控制跨站发送范围,用 Secure 限制为 HTTPS,再用 HttpOnly 降低脚本直接读取的风险;Cookie 的生存期则由 MaxAgeExpires 决定。

普通同站登录优先考虑 SameSite=LaxSecure=trueHttpOnly=true;确实需要跨站携带时才使用 SameSite=None,并且必须同时打开 Secure
要点速览
  • SameSite 决定跨站请求是否带 Cookie,Secure 决定是否只在 HTTPS 请求中发送。
  • MaxAge>0 表示秒数,MaxAge 表示立即删除,MaxAge=0 表示不写入 Max-Age。
  • 排查时看服务端最终发出的 Set-Cookie,不要只看 Go 结构体的初始值。

一、先分清 Cookie 属性各自控制什么

http.Cookie 同时表示响应里的 Set-Cookie 和请求里的 Cookie。写响应时最容易混淆的是几个布尔值和生命周期字段,它们并不是同一个层面的开关。

字段作用常见选择
SameSite限制跨站请求是否携带Lax、Strict、None
Secure仅通过 HTTPS 发送(localhost 有例外)生产环境通常为 true
HttpOnly禁止 JavaScript 通过 Document.cookie 读取登录态通常为 true
MaxAge以秒定义生存期或删除动作正数、0、负数

这些字段不能替代服务端的身份校验和 CSRF 防护。比如 HttpOnly 仍允许浏览器把 Cookie 随请求发送,Secure 也不等于 Cookie 内容绝对不会被读取。

Go http.Cookie 的 SameSite、Secure、HttpOnly 与 MaxAge 静态属性边界关系图
图1:查看 http.Cookie 字段、浏览器发送条件和生命周期边界之间的静态关系。

二、用 http.Cookie 生成登录态 Cookie

服务端直接构造结构体,再交给 http.SetCookie 序列化。下面的例子把 Cookie 限定到根路径,设置两小时有效期,并让浏览器只在 HTTPS 请求中发送。

package main

import (
    "net/http"
    "time"
)

func issueSession(w http.ResponseWriter) {
    cookie := &http.Cookie{
        Name:     "session_id",
        Value:    "opaque-session-value",
        Path:     "/",
        MaxAge:   int((2 * time.Hour).Seconds()), // 正数表示存活秒数
        Secure:   true,                           // 生产环境要求 HTTPS
        HttpOnly: true,                           // 禁止脚本直接读取
        SameSite: http.SameSiteLaxMode,           // 同站请求及合适的顶层导航
    }
    http.SetCookie(w, cookie)
}

这里不要写 SameSite: "Lax",因为 Go 使用 http.SameSiteLaxMode 等枚举值。SetCookie 会把结构体序列化为响应头;Cookie 名称非法时,String 会返回空字符串,因此名称和值也要使用合法的 Cookie 字符。

如果登录态只服务于后端接口,HttpOnly 通常应保留为 true。前端需要读取的主题偏好等非敏感 Cookie,才另行评估是否允许脚本访问。

三、SameSite 选择要和跨站场景对应

SameSite=Strict 只允许同站请求,限制最强,但用户从外部站点点击链接回到业务页时,登录态体验可能受影响。Lax 允许同站请求和符合条件的跨站顶层安全导航,是许多普通网页登录的折中。None 允许跨站和同站请求,必须同时设置 Secure,适合确实存在跨站嵌入或跨站回调的场景。

选择前先问清楚“站”而不是只看域名:跨站判断包含 scheme。开发环境用 HTTP 访问时,SameSite=None; Secure 往往无法按预期工作;生产环境应使用 HTTPS,并在反向代理终止 TLS 时确认应用能正确识别外部协议。

Go SameSite 三种模式与 Secure HTTPS 发送条件的静态关系图
图2:对照 Strict、Lax、None 三个模式与 Secure、HTTPS、跨站请求条件的静态关系。

四、过期时间与 Set-Cookie 排查清单

MaxAge=0 表示不生成 Max-Age 属性,通常得到会话 Cookie;MaxAge>0 生成按秒计算的生存期;MaxAge 表示立即删除 Cookie。若同时设置 ExpiresMaxAge,浏览器以 Max-Age 为优先。

要删除旧 Cookie,必须尽量复用原来的 NamePathDomain,并把 MaxAge 设为负数。只改名称或路径,可能只是新增了另一个 Cookie,旧值仍然存在。

  • 响应是否真的包含 Set-Cookie,而不是只在日志里打印结构体。
  • SameSite=None 是否同时有 Secure,生产请求是否为 HTTPS。
  • 删除时的路径和域是否与创建时一致,MaxAge 是否为负数。
  • 是否误把 Expires 的时区或过期时间写错,并以为它覆盖了正的 MaxAge

官方 Go 文档说明,Cookie.String 用于生成 Cookie 或 Set-Cookie 的序列化文本;因此排查应以浏览器网络面板或服务端实际响应头为准,而不是猜测字段是否被拼接。

相关问题

SameSite=None 为什么必须配 Secure?

这是浏览器对跨站 Cookie 的组合要求。Go 能够序列化两个字段,但如果没有 Secure,浏览器不会按跨站 Cookie 预期接受或发送它。

Secure=true 在本地 HTTP 调试会怎样?

除 localhost 等特殊情况外,Cookie 只应随 HTTPS 请求发送。开发环境若使用普通 HTTP,先确认测试目标,再用本地 HTTPS 或调整仅限开发的配置。

MaxAge 和 Expires 应该只选一个吗?

可以同时设置,但要明确优先级:浏览器在两者同时存在时以 Max-Age 为准。跨客户端兼容时可同时提供,并保证它们表达同一个过期意图。

参考:Go net/http.Cookie 文档MDN Set-Cookie 属性说明

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>