package authser import "github.com/gin-gonic/gin" // TokenExpiredCode 上游约定:token 失效,需重新登录。 const TokenExpiredCode = 1000 // IsSessionExpiredCode 是否为会话失效类业务码。 func IsSessionExpiredCode(code int) bool { switch code { case TokenExpiredCode, 1002, 1012, 6001: // InvalidToken / NoToken / InvalidateToken / 用户不存在 return true default: return false } } // OnSessionExpired 处理上游会话失效。 // retry=true:游客已重新登录,调用方应重试原请求; // needLogin=true:注册账号已清 cookie,调用方应跳转登录弹窗/页。 func OnSessionExpired(c *gin.Context, code int) (retry, needLogin bool) { if c == nil || !IsSessionExpiredCode(code) { return false, false } if IsRegisteredFromCookies(c) { ClearAuthCookies(c) dropRequestCookie(c, "token") dropRequestCookie(c, "_token_") // 正式账号失效后,本请求保持退出态,避免后续 HTML 渲染又静默转成游客。 suppressRequestAutoAuth(c) return false, true } if RefreshGuestSession(c) != nil { return true, false } ClearAuthCookies(c) dropRequestCookie(c, "token") dropRequestCookie(c, "_token_") return false, false } // RecoverContentSession 用于允许游客访问的内容读取接口。 // 正式账号或游客 token 失效后,清理旧登录态、重新建立游客会话,调用方随后重试一次原请求。 // 写操作仍应使用 OnSessionExpired,避免把用户操作静默降级为游客操作。 func RecoverContentSession(c *gin.Context, code int) bool { if c == nil || !IsSessionExpiredCode(code) { return false } ClearAuthCookies(c) for _, name := range authCookieNames() { dropRequestCookie(c, name) } dropRequestCookie(c, guestSkipAutoCookie) ClearGuestSkipAuto(c) // 内容读取接口明确允许降级为游客,因此覆盖本请求可能已有的自动认证抑制。 allowRequestAutoAuth(c) return EnsureGuestOnEnter(c) != nil }