- 添加用户退出路由 (/logout),清除会话信息并重定向到登录页 - 重新设计登录页面,增加样式和布局,提升用户体验 - 更新登录表单,添加占位符和错误消息显示 - 修改服务器端口为 7070
121 lines
2.9 KiB
Go
121 lines
2.9 KiB
Go
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")
|
|
}
|