feat(gateway): 增加用户信息并在日志中记录

- 新增 getUserInfo 辅助函数以获取用户信息
- 更新 ServeIndex 和 ServeStatic 函数以使用数据库参数
- 修改 LogAccess 函数以记录用户信息
- 优化 AuthRequired 中间件,对登出操作进行特殊处理
This commit is contained in:
高手 2025-02-16 10:06:32 +08:00
parent 42fcb4f754
commit fbed496bed
4 changed files with 61 additions and 17 deletions

View File

@ -4,20 +4,48 @@ import (
"net/http" "net/http"
"os" "os"
"gateway/models"
"gateway/utils" "gateway/utils"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
) )
// 获取用户信息的辅助函数
func getUserInfo(c *gin.Context, db *gorm.DB) map[string]interface{} {
session := sessions.Default(c)
userID := session.Get("user")
if userID == nil {
return nil
}
var user models.User
if err := db.Preload("Region").First(&user, userID).Error; err != nil {
return nil
}
return map[string]interface{}{
"user_id": user.ID,
"full_name": user.FullName,
"region": user.Region.Name,
}
}
// 处理首页请求 // 处理首页请求
func ServeIndex(c *gin.Context) { func ServeIndex(db *gorm.DB) gin.HandlerFunc {
utils.LogAccess(c.ClientIP(), c.Request.URL.Path, c.Request.Method) return func(c *gin.Context) {
userInfo := getUserInfo(c, db)
utils.LogAccess(c.ClientIP(), c.Request.URL.Path, c.Request.Method, userInfo)
http.ServeFile(c.Writer, c.Request, "./static/index.html") http.ServeFile(c.Writer, c.Request, "./static/index.html")
} }
}
// 处理静态文件请求 // 处理静态文件请求
func ServeStatic(c *gin.Context) { func ServeStatic(db *gorm.DB) gin.HandlerFunc {
utils.LogAccess(c.ClientIP(), c.Request.URL.Path, c.Request.Method) return func(c *gin.Context) {
userInfo := getUserInfo(c, db)
utils.LogAccess(c.ClientIP(), c.Request.URL.Path, c.Request.Method, userInfo)
filePath := "./static" + c.Request.URL.Path filePath := "./static" + c.Request.URL.Path
if _, err := os.Stat(filePath); err == nil { if _, err := os.Stat(filePath); err == nil {
http.ServeFile(c.Writer, c.Request, filePath) http.ServeFile(c.Writer, c.Request, filePath)
@ -25,3 +53,4 @@ func ServeStatic(c *gin.Context) {
c.AbortWithStatus(http.StatusNotFound) c.AbortWithStatus(http.StatusNotFound)
} }
} }
}

View File

@ -55,13 +55,13 @@ func main() {
r.Use(middleware.AuthRequired()) r.Use(middleware.AuthRequired())
// 文档页面路由 // 文档页面路由
r.GET("/", handlers.ServeIndex) r.GET("/", handlers.ServeIndex(db))
// 在权限校验中间件后添加退出路由 // 在权限校验中间件后添加退出路由
r.GET("/logout", handlers.Logout) r.GET("/logout", handlers.Logout)
// 新增通用静态文件路由(放在其他路由之后) // 新增通用静态文件路由(放在其他路由之后)
r.NoRoute(handlers.ServeStatic) r.NoRoute(handlers.ServeStatic(db))
// 启动服务 // 启动服务
r.Run(":7070") r.Run(":7070")

View File

@ -13,9 +13,15 @@ func AuthRequired() gin.HandlerFunc {
session := sessions.Default(c) session := sessions.Default(c)
user := session.Get("user") user := session.Get("user")
if user == nil { if user == nil {
// 获取当前请求的完整URL // 如果是登出路径,直接重定向到登录页面
if c.Request.URL.Path == "/logout" {
c.Redirect(http.StatusFound, "/login")
c.Abort()
return
}
// 对于其他路径,保留原有的return_url逻辑
returnURL := c.Request.URL.String() returnURL := c.Request.URL.String()
// URL编码处理避免特殊字符造成问题
encodedURL := url.QueryEscape(returnURL) encodedURL := url.QueryEscape(returnURL)
c.Redirect(http.StatusFound, "/login?return_url="+encodedURL) c.Redirect(http.StatusFound, "/login?return_url="+encodedURL)
c.Abort() c.Abort()

View File

@ -27,11 +27,20 @@ func InitLogger() {
Logger.SetOutput(io.MultiWriter(os.Stdout, logFile)) Logger.SetOutput(io.MultiWriter(os.Stdout, logFile))
} }
func LogAccess(ip, path, method string) { func LogAccess(ip, path, method string, userInfo map[string]interface{}) {
Logger.WithFields(logrus.Fields{ fields := logrus.Fields{
"ip": ip, "ip": ip,
"path": path, "path": path,
"method": method, "method": method,
"timestamp": time.Now().Format(time.RFC3339), "timestamp": time.Now().Format(time.RFC3339),
}).Info("Page accessed") }
// 合并用户信息到日志字段中
if userInfo != nil {
for k, v := range userInfo {
fields[k] = v
}
}
Logger.WithFields(fields).Info("Page accessed")
} }