登出必须服务端主动失效,仅前端清除 localstorage 或 cookie 不安全;应使用 redis 黑名单(存 jti)或 gin-contrib/sessions + redis 管理服务端状态,并严格匹配 cookie 属性覆盖、校验 token 有效性、防范开放重定向。

登出时必须清除服务端 Session 或 Token
只前端清 localStorage 或删 Cookie 不算登出,攻击者仍可用旧 Token 访问接口。Gin 本身不内置 Session 管理,你得自己选方案:用 gin-contrib/sessions 配 Redis 存服务端 session,或用 JWT + Redis 黑名单(redis.Set("blacklist:"+tokenID, "1", expire))。若用 JWT 且没存黑名单,登出只能靠缩短 exp 时间,本质是“被动失效”,不安全。
Cookie 清除要匹配 Set-Cookie 的所有属性
后端调 c.SetCookie() 写的 Cookie,登出时得用完全一致的 Path、Domain、Secure、HttpOnly 参数覆盖为过期值,否则浏览器可能残留有效 Cookie。常见错误是漏写 Domain 或把 Secure: true 写成 false(HTTPS 环境下)。
示例正确写法:
c.SetCookie("auth_token", "", -1, "/admin", "example.com", true, true)
注意:MaxAge: -1 表示立即过期;Path 和 Domain 必须和登录时写入的一致。
登出接口必须校验当前请求的 Token / Session 有效性
不能只依赖前端传来的 token 字符串就直接删 Redis key。先用该 token 查一次用户身份(比如 redis.Get("session:" + token)),确认它确实存在且未被提前踢出,再执行删除。否则攻击者可批量发登出请求制造拒绝服务(如高频调 DEL session:xxx)。
关键检查点:
- Token 是否在黑名单中(已主动登出或被吊销)
- Session 数据是否完整(避免空指针或 JSON 解析失败)
- 请求 IP 或 User-Agent 是否与登录时明显不符(可选风控增强)
登出后重定向到登录页需防开放重定向漏洞
别直接读取请求参数里的 redirect 值做 c.Redirect(http.StatusFound, redirect)。攻击者可构造 ?redirect=https://evil.com 把管理员骗离你的域。应白名单校验跳转路径,例如只允许以 /admin/login 或 /login 开头的相对路径。
简单判断逻辑:
redirect := c.DefaultQuery("redirect", "/admin/login")
if !strings.HasPrefix(redirect, "/admin/") && redirect != "/login" {
redirect = "/admin/login"
}
c.Redirect(http.StatusFound, redirect)
登出看似只是删个 key,但涉及 Cookie 生命周期、服务端状态一致性、重定向安全边界三个层面。漏掉任意一环,都可能让“已登出”变成“假登出”。











