package api import ( "augment2api/config" "augment2api/pkg/logger" "net/http" "time" "github.com/gin-gonic/gin" "github.com/google/uuid" ) const ( TokenKey = "login:token:" ) // 生成随机会话令牌 func generateSessionToken() string { tokenUUID := uuid.New() return tokenUUID.String() } // LoginRequest 登录请求结构 type LoginRequest struct { Password string `json:"password"` } // LoginHandler 处理登录请求 func LoginHandler(c *gin.Context) { var req LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "status": "error", "error": "无效的请求数据", }) return } // 验证密码 if req.Password == config.AppConfig.AccessPwd { // 生成会话令牌 token := generateSessionToken() // 将会话令牌保存到Redis,有效期24小时 sessionKey := TokenKey + token err := config.RedisSet(sessionKey, "valid", 24*time.Hour) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "status": "error", "error": "保存会话失败: " + err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "status": "success", "token": token, }) return } // 密码错误 c.JSON(http.StatusUnauthorized, gin.H{ "status": "error", "error": "密码错误", }) } // ValidateToken 验证Token func ValidateToken(token string) bool { if token == "" { return false } // 检查Redis中是否存在该token tokenKey := TokenKey + token exists, err := config.RedisExists(tokenKey) if err != nil || !exists { return false } return true } // AuthTokenMiddleware 会话认证中间件 func AuthTokenMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 如果未设置访问密码,则不需要验证 if config.AppConfig.AccessPwd == "" { c.Next() return } // 从查询参数或Cookie中获取会话令牌 token := c.GetHeader("X-Auth-Token") if token == "" { token = c.Query("token") } if token == "" { token, _ = c.Cookie("auth_token") } // 验证会话令牌 if !ValidateToken(token) { logger.Log.Info("无效的会话令牌:", token) c.Redirect(http.StatusFound, "/login?error=token_expired") c.Abort() return } c.Next() } } // LogoutHandler 处理登出请求 func LogoutHandler(c *gin.Context) { token := c.GetHeader("X-Auth-Token") if token != "" { // 从Redis中删除会话token tokenKey := TokenKey + token err := config.RedisDel(tokenKey) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "status": "error", "error": "删除会话失败: " + err.Error(), }) return } } c.JSON(http.StatusOK, gin.H{ "status": "success", }) }