package routers import ( "fmt" "go_blog/controllers" "go_blog/controllers/admin" "net/http" "time" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) // CheckAdminAuth 后台认证中间件(处理页面重定向) func CheckAdminAuth() gin.HandlerFunc { return func(c *gin.Context) { currentPath := c.Request.URL.Path session := sessions.Default(c) // 获取当前请求的Session userID := session.Get("user_id") // 从Session中获取用户ID loggedIn := userID != nil && userID != "" // 已登录状态访问登录/注册页:重定向到后台首页 if (currentPath == "/admin/login" || currentPath == "/admin/register") && loggedIn { c.Redirect(http.StatusFound, "/admin/index") c.Abort() return } // 未登录状态访问非登录/注册页:重定向到登录页 if (currentPath != "/admin/login" && currentPath != "/admin/register") && !loggedIn { c.Redirect(http.StatusFound, "/admin/login") c.Abort() return } c.Next() } } // SessionAuthRequired 基于Session的认证中间件 func SessionAuthRequired() gin.HandlerFunc { return func(c *gin.Context) { session := sessions.Default(c) userID := session.Get("user_id") if userID == nil { // 未登录,重定向到登录页 c.Redirect(http.StatusFound, "/admin/login") c.Abort() return } // 可选:根据userID查询用户信息并注入上下文 // user, err := models.GetAccountByID(userID.(uint)) // if err != nil { ... } // c.Set("user", user) c.Next() } } func RegisterRoutes(r *gin.Engine) { // WebSocket 和 SSE 路由 r.GET("/events", esSSE) r.GET("/ws", controllers.WebSocketHandler) // 内容相关路由 r.POST("/content", controllers.CreateContentHandler) r.GET("/page", controllers.PageList) r.GET("/createcontent", controllers.CreateContentPage) // 前端路由(动态主题) r.GET("/", controllers.Home) r.GET("/post/:id", controllers.ShowPost) adminGroup := r.Group("/admin") adminGroup.Use(CheckAdminAuth()) { // 无需认证的公开路由(登录/注册) // 新增:处理 /admin 根路径跳转 adminGroup.GET("/", func(c *gin.Context) { // 由于 CheckAdminAuth 中间件已处理未登录场景,此处用户必定已登录 c.Redirect(http.StatusFound, "/admin/index") }) adminGroup.GET("/login", admin.ShowLoginPage) adminGroup.GET("/register", admin.ShowRegisterPage) adminGroup.POST("/login", admin.UsersLoginHandler) adminGroup.POST("/register", admin.UsersRegisterHandler) // 需要认证的路由组 authAdmin := adminGroup.Group("", SessionAuthRequired()) { authAdmin.GET("/index", admin.ShowAdminIndexPage) authAdmin.GET("/themes", admin.ListThemes) authAdmin.POST("/themes/switch", admin.SwitchTheme) authAdmin.POST("/setpwd", admin.UsersSetPwdHandler) authAdmin.GET("/logout", admin.UsersLogoutHandler) // 添加退出路由 } } // Static files for themes r.StaticFS("/themes", http.Dir("web/themes")) } func esSSE(c *gin.Context) { w := c.Writer w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") w.Header().Set("Access-Control-Allow-Origin", "*") flusher, ok := w.(http.Flusher) if !ok { c.String(http.StatusInternalServerError, "server not support SSE") return } for { fmt.Fprintf(w, "data: %s\n\n", time.Now().Format(time.Stamp)) flusher.Flush() time.Sleep(1 * time.Second) } }