jdysya 3014f8acf6 feat(gateway): 新增通用静态文件路由
- 在 main.go 中添加了通用静态文件路由
- 路由会检查请求路径对应的静态文件是否存在,若存在则返回文件,否则返回 404
- 此功能便于后续添加前端路由和实现 PWA(渐进式 Web 应用)
2025-02-15 14:03:21 +08:00

132 lines
3.2 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.NoRoute(func(c *gin.Context) {
filePath := "./static" + c.Request.URL.Path
// 检查文件是否存在
if _, err := os.Stat(filePath); err == nil {
http.ServeFile(c.Writer, c.Request, filePath)
} else {
c.AbortWithStatus(http.StatusNotFound)
}
})
// 启动服务
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")
}