c.Cookies("key") 返回空不是 Fiber 读取失败,而是浏览器未发送 Cookie,主因是 credentials 配置缺失、Secure 属性与协议不匹配、Path/Domain 不匹配导致作用域失效。

为什么 c.Cookies("key") 总是返回空
不是 Fiber 读取失败,而是浏览器根本没把 Cookie 发过来。常见原因有三个:credentials: "include" 没加、Secure 和当前协议不匹配、Path 或 Domain 配置导致匹配失败。
- 前端用 Fetch 时必须显式加
credentials: "include";Axios 要设withCredentials: true - 开发环境用
http://localhost却设置了Secure: true,浏览器直接丢弃该 Cookie -
Set-Cookie: auth_token=xxx; Path=/admin,你在/user路由里调c.Cookies("auth_token")就是空——Fiber 不自动 fallback 到父路径 - Cookie 值含中文或空格,
c.Cookies("key")返回的是 URL 编码后字符串,得手动url.QueryUnescape()
写 Cookie 必须显式设置 Secure、HttpOnly、SameSite
只设 Name 和 Value 是生产环境失效的主因。Fiber 不自动补安全属性,漏一项就可能被浏览器拒绝发送或遭 XSS 盗取。
-
Secure: true:HTTPS 环境下必须为true;HTTP 开发环境可设false,但更推荐本地启 HTTPS(如 mkcert) -
HTTPOnly: true:阻止 JavaScript 访问,防 XSS 盗 token -
SameSite推荐用fiber.SameSiteLaxMode(默认),仅跨站 GET 安全携带;若需跨站 POST(如 OAuth 回调),才用fiber.SameSiteNoneMode,且必须配Secure: true -
MaxAge比Expires更可靠,避免客户端时间偏差;JWT 类 Cookie 建议让MaxAge与 token 的exp字段对齐
c.Cookies() 返回的是原始字符串,不是解析后值
c.Cookies("jwt") 拿到的是 Base64Url 编码的三段字符串(header.payload.signature),不是用户 ID,也不是 JSON 对象。跳过解析直接用等于信任前端传来的任意数据。
- 不能
json.Unmarshal([]byte(c.Cookies("jwt")), &v)—— payload 还没解码,会解析失败 - 正确流程:取值 →
strings.SplitN(..., ".", 3)拆分 →base64.RawURLEncoding.DecodeString()解码 payload →jwt.Parse()校验签名和exp/nbf - 多个同名 Cookie(如不同
Path)共存时,c.Cookies()只返回请求头中第一个匹配项,顺序取决于客户端构造 - 如果需要加密 Cookie,Fiber 官方不提供
EncryptCookie中间件;可用github.com/gofiber/encrypt(仅解密请求 Cookie),响应 Cookie 仍需手动加密后调c.SetCookie()
Session 不是 Fiber 内置功能,必须外接中间件
Fiber 默认不带 Session 支持,所谓“内存 session”只是开发调试用的临时 map,多实例或重启即丢,且并发写会 panic。
- 生产必须用持久化存储:Redis(推荐)、Badger、PostgreSQL,通过
github.com/gofiber/session+ 对应storage适配器 - Redis 存储要注意连接池配置,高并发下
GET/SET易成瓶颈;建议显式设session.Config{Expiration: 1800} - CSRF 防护依赖 Session:启用
csrf.New()后,若配了会话存储,自动切换为同步令牌模式(令牌存在服务端 session 中),比双提交 Cookie 更安全 - 别在中间件外直接读
c.Locals("user")——确保路由已挂载认证中间件,且请求带了合法Authorization: Bearer xxx或对应 Cookie
c.Cookies() 返回的是可信值,其实它只是 HTTP 头里的一串字符串——校验、解码、签名验证,全得自己写。


















