package main import ( "fmt" "net/http" "os" "time" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) var logger = logrus.New() func init() { // 配置日志格式 logger.SetFormatter(&logrus.JSONFormatter{}) logger.SetOutput(os.Stdout) } func main() { // 初始化 Gin 引擎 r := gin.Default() // 配置静态文件服务 r.Static("/assets", "./static/assets") r.LoadHTMLGlob("templates/*") // 配置 Session 中间件 store := cookie.NewStore([]byte("secret")) store.Options(sessions.Options{ MaxAge: 86400 * 7, HttpOnly: true, Secure: false, // 如果是HTTPS需要设为true SameSite: http.SameSiteLaxMode, // 允许跨站携带cookie }) r.Use(sessions.Sessions("mysession", store)) // 登录页面 r.GET("/login", func(c *gin.Context) { c.HTML(http.StatusOK, "login.html", nil) }) // 处理登录请求 r.POST("/login", func(c *gin.Context) { username := c.PostForm("username") password := c.PostForm("password") if username == "admin" && password == "123" { session := sessions.Default(c) session.Set("user", username) if err := session.Save(); err != nil { logger.Errorf("Session保存失败: %v", err) c.HTML(http.StatusInternalServerError, "login.html", gin.H{"error": "登录状态保存失败"}) return } c.Redirect(http.StatusSeeOther, "/") // 改用303状态码 return } c.HTML(http.StatusUnauthorized, "login.html", gin.H{"error": "用户名或密码错误"}) }) // 权限校验中间件 authMiddleware := func(c *gin.Context) { session := sessions.Default(c) user := session.Get("user") if user == nil { c.Redirect(http.StatusFound, "/login") c.Abort() return } c.Next() } // 文档页面路由 r.Use(authMiddleware) r.GET("/", func(c *gin.Context) { // 记录访问痕迹 logAccess(c) http.ServeFile(c.Writer, c.Request, "./static/index.html") }) r.GET("/guide/:page", func(c *gin.Context) { // 记录访问痕迹 logAccess(c) page := c.Param("page") http.ServeFile(c.Writer, c.Request, fmt.Sprintf("./static/guide/%s.html", page)) }) // 在权限校验中间件后添加退出路由 r.GET("/logout", func(c *gin.Context) { session := sessions.Default(c) session.Clear() if err := session.Save(); err != nil { logger.Errorf("退出登录失败: %v", err) c.HTML(http.StatusInternalServerError, "error.html", gin.H{"error": "退出登录失败"}) return } c.Redirect(http.StatusSeeOther, "/login") }) // 启动服务 r.Run(":7070") } // 记录访问痕迹 func logAccess(c *gin.Context) { ip := c.ClientIP() path := c.Request.URL.Path method := c.Request.Method timestamp := time.Now().Format(time.RFC3339) logger.WithFields(logrus.Fields{ "ip": ip, "path": path, "method": method, "timestamp": timestamp, }).Info("Page accessed") }