fix: 第一轮修复 - 记忆管理/IoT操控/历史消息持久化/动作消息/链路优化/安全配置
- 修复记忆管理数据库连接不可用 (ai-core重编译+Unicode修复) - 修复IoT子会话工具调用链路日志缺失 - 新增最终审查子会话(review_provider) 支持消息格式解析拆分 - 实现历史消息持久化(后端存储+前端分页加载) - 前端新增动作消息(ActionMessage)类型和渲染 - 优化对话链路速度(非阻塞子会话+快速问候通道) - JWT密钥环境变量化(无默认值启动panic) - Token自动刷新机制(401拦截器+refresh接口) - WebSocket指数退避重连(jitter+最大10次) - localStorage清理一致性(cyrene_前缀+版本检查) - IoT环境变量统一为IOT_SERVICE_URL
This commit is contained in:
@@ -108,11 +108,19 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 生成 refresh_token (长期有效)
|
||||
refreshToken, err := h.cfg.GenerateRefreshToken(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "生成刷新令牌失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"user_id": userID,
|
||||
"token": token,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
"nickname": req.Nickname,
|
||||
"user_id": userID,
|
||||
"token": token,
|
||||
"refresh_token": refreshToken,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
"nickname": req.Nickname,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -186,10 +194,18 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 生成 refresh_token (长期有效)
|
||||
refreshToken, err := h.cfg.GenerateRefreshToken(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "生成刷新令牌失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user_id": userID,
|
||||
"token": token,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
"user_id": userID,
|
||||
"token": token,
|
||||
"refresh_token": refreshToken,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -219,18 +235,38 @@ func (h *AuthHandler) verifyUserPassword(username, password string) (bool, error
|
||||
}
|
||||
|
||||
// RefreshToken 刷新令牌
|
||||
// 支持两种方式:
|
||||
// 1. 在 Authorization header 中传入有效的 access_token (可以已过期但 refresh_token 有效)
|
||||
// 2. 在请求体中传入 refresh_token
|
||||
func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" || len(authHeader) < 8 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供认证令牌"})
|
||||
return
|
||||
}
|
||||
var userID string
|
||||
|
||||
tokenString := authHeader[7:] // 去掉 "Bearer "
|
||||
userID, err := h.cfg.ValidateToken(tokenString)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "令牌无效或已过期"})
|
||||
return
|
||||
// 优先从请求体获取 refresh_token
|
||||
var req struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err == nil && req.RefreshToken != "" {
|
||||
uid, err := h.cfg.ValidateRefreshToken(req.RefreshToken)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "刷新令牌无效或已过期"})
|
||||
return
|
||||
}
|
||||
userID = uid
|
||||
} else {
|
||||
// 回退:从 Authorization header 获取 access_token 并验证
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" || len(authHeader) < 8 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供认证令牌"})
|
||||
return
|
||||
}
|
||||
|
||||
tokenString := authHeader[7:] // 去掉 "Bearer "
|
||||
uid, err := h.cfg.ValidateToken(tokenString)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "令牌无效或已过期"})
|
||||
return
|
||||
}
|
||||
userID = uid
|
||||
}
|
||||
|
||||
newToken, err := h.cfg.GenerateToken(userID)
|
||||
@@ -239,8 +275,16 @@ func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 生成新的 refresh_token
|
||||
newRefreshToken, err := h.cfg.GenerateRefreshToken(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "生成刷新令牌失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"token": newToken,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
"token": newToken,
|
||||
"refresh_token": newRefreshToken,
|
||||
"expires": time.Now().Add(h.cfg.JWTExpiryHours).Unix(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user