fix: 管理会话自动恢复与访问来源统计优化
- 新增 AdminSessionRecover:后台离线/后端重启时自动重试恢复会话,明确失效才回跳登录 - 认证 cookie 契约调整(SameSite=Lax 与刷新轮转适配),路由与守卫适配 - 访问来源统计查询优化与测试、管理端 analytics sources 页面适配 - 移动端布局修正:覆盖 body min-h-screen 避免内容区高度异常
This commit is contained in:
@@ -242,13 +242,21 @@ func (h *Handlers) Refresh(c *gin.Context) {
|
||||
}
|
||||
accessToken, newRefresh, user, err := h.Auth.RotateRefreshToken(refreshToken, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
clearAuthCookies(c, !h.Cfg.DevMode)
|
||||
if errors.Is(err, service.ErrAccountBanned) {
|
||||
// 账号已封禁:清 cookie 的同时给出可识别 code,前端弹封禁告知并强制下线
|
||||
clearAuthCookies(c, !h.Cfg.DevMode)
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "账号已被封禁", "code": "account_banned"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "登录已过期,请重新登录"})
|
||||
if errors.Is(err, service.ErrRefreshInvalid) || errors.Is(err, service.ErrRefreshExpired) {
|
||||
// 登录态确实失效:清 cookie 要求重新登录(前端弹"登录已失效")
|
||||
clearAuthCookies(c, !h.Cfg.DevMode)
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "登录已过期,请重新登录"})
|
||||
return
|
||||
}
|
||||
// 其他错误(数据库抖动等):服务暂不可用。保留 cookie 等下次刷新,
|
||||
// 前端按瞬态失败处理(不弹"登录已失效"、不强制重登)
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "登录刷新暂不可用,请稍后重试"})
|
||||
return
|
||||
}
|
||||
setAuthCookies(c, accessToken, newRefresh, !h.Cfg.DevMode)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/freefire/jiang13-bbs/middleware"
|
||||
@@ -16,13 +17,20 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// maxSearchKeywordRunes 帖子搜索关键词长度上限(字符数,与前端搜索框 maxLength 一致)
|
||||
const maxSearchKeywordRunes = 100
|
||||
|
||||
// Posts 获取帖子列表
|
||||
func (h *Handlers) Posts(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
||||
boardID, _ := strconv.ParseUint(c.Query("board_id"), 10, 64)
|
||||
sort := c.DefaultQuery("sort", "latest")
|
||||
keyword := c.Query("keyword")
|
||||
keyword := strings.TrimSpace(c.Query("keyword"))
|
||||
// 搜索词上限:前端输入框同限;超长词 ILIKE 必然无意义结果,静默截断
|
||||
if runes := []rune(keyword); len(runes) > maxSearchKeywordRunes {
|
||||
keyword = string(runes[:maxSearchKeywordRunes])
|
||||
}
|
||||
recommended := c.Query("recommended") == "true"
|
||||
|
||||
var viewerID uint
|
||||
|
||||
Reference in New Issue
Block a user