修改middleware包
This commit is contained in:
@@ -1,25 +1,25 @@
|
|||||||
- **`internal/app/middleware/auth.go`**
|
- **`internal/app/middleware/auth.go`**
|
||||||
- **中间件函数改造 (`AuthMiddleware`)**:
|
- **中间件函数改造 (`AuthMiddleware`)**:
|
||||||
- [ ] 在 `AuthMiddleware` 返回的 `echo.HandlerFunc` 内部,获取 `echo.Context` 的 `request.Context()` 作为
|
- [x] 在 `AuthMiddleware` 返回的 `echo.HandlerFunc` 内部,获取 `echo.Context` 的 `request.Context()` 作为
|
||||||
`upstreamCtx`。
|
`upstreamCtx`。
|
||||||
- [ ] 使用 `newCtx, logger := logs.Trace(upstreamCtx, context.Background(), "AuthMiddleware")` 来创建 `newCtx`
|
- [x] 使用 `newCtx, logger := logs.Trace(upstreamCtx, context.Background(), "AuthMiddleware")` 来创建 `newCtx`
|
||||||
和 `logger` 实例。
|
和 `logger` 实例。
|
||||||
- [ ] 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `newCtx` 写入 `echo.Context`,以便后续处理链使用。
|
- [x] 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `newCtx` 写入 `echo.Context`,以便后续处理链使用。
|
||||||
- [ ] 将所有对 `controller.SendErrorWithStatus` 的调用替换为 `controller.SendErrorWithAudit`。
|
- [x] 将所有对 `controller.SendErrorWithStatus` 的调用替换为 `controller.SendErrorWithAudit`。
|
||||||
- [ ] 确保 `controller.SendErrorWithAudit` 接收 `newCtx` 作为第一个参数,并提供适当的 `actionType`,
|
- [x] 确保 `controller.SendErrorWithAudit` 接收 `newCtx` 作为第一个参数,并提供适当的 `actionType`,
|
||||||
`description`, `targetResource`。
|
`description`, `targetResource`。
|
||||||
- 例如,对于“请求未包含授权标头”的错误,`actionType` 可以是“认证失败”,`description` 是“请求未包含授权标头”,
|
- 例如,对于“请求未包含授权标头”的错误,`actionType` 可以是“认证失败”,`description` 是“请求未包含授权标头”,
|
||||||
`targetResource` 为 `nil`。
|
`targetResource` 为 `nil`。
|
||||||
- 对于“无效的Token”错误,`actionType` 可以是“认证失败”,`description` 是“无效的Token”,`targetResource` 是
|
- 对于“无效的Token”错误,`actionType` 可以是“认证失败”,`description` 是“无效的Token”,`targetResource` 是
|
||||||
`tokenString`。
|
`tokenString`。
|
||||||
- [ ] 在 `AuthMiddleware` 内部,如果需要日志记录(例如 `tokenService.ParseToken` 失败或 `userRepo.FindByID`
|
- [x] 在 `AuthMiddleware` 内部,如果需要日志记录(例如 `tokenService.ParseToken` 失败或 `userRepo.FindByID`
|
||||||
失败),使用新创建的 `logger` 实例进行日志输出。
|
失败),使用新创建的 `logger` 实例进行日志输出。
|
||||||
- [ ] **关键**: 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `Context` 写回 `echo.Context`
|
- [x] **关键**: 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `Context` 写回 `echo.Context`
|
||||||
,以便传递给后续的中间件和 `Controller`。
|
,以便传递给后续的中间件和 `Controller`。
|
||||||
- **`internal/app/middleware/audit.go`**
|
- **`internal/app/middleware/audit.go`**
|
||||||
- **改造动作**:
|
- **改造动作**:
|
||||||
- [ ] 检查并重构所有日志记录中间件。
|
- [x] 检查并重构所有日志记录中间件。
|
||||||
- [ ] 中间件应该从请求的 `c.Request().Context()` 中提取 `upstreamCtx`。
|
- [x] 中间件应该从请求的 `c.Request().Context()` 中提取 `upstreamCtx`。
|
||||||
- [ ] 使用 `logs.Trace` 或 `logs.AddFuncName` 创建新的 `Context` 和 `Logger`。
|
- [x] 使用 `logs.Trace` 或 `logs.AddFuncName` 创建新的 `Context` 和 `Logger`。
|
||||||
- [ ] **关键**: 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `Context` 写回 `echo.Context`
|
- [x] **关键**: 使用 `c.SetRequest(c.Request().WithContext(newCtx))` 将更新后的 `Context` 写回 `echo.Context`
|
||||||
,以便传递给后续的中间件和 `Controller`。
|
,以便传递给后续的中间件和 `Controller`。
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
|
|
||||||
@@ -52,8 +53,8 @@ func (a *API) setupRoutes() {
|
|||||||
// --- Authenticated Routes ---
|
// --- Authenticated Routes ---
|
||||||
// 所有在此注册的路由都需要通过 JWT 身份验证
|
// 所有在此注册的路由都需要通过 JWT 身份验证
|
||||||
authGroup := a.echo.Group("/api/v1")
|
authGroup := a.echo.Group("/api/v1")
|
||||||
authGroup.Use(middleware.AuthMiddleware(a.tokenService, a.userRepo)) // 1. 身份认证中间件
|
authGroup.Use(middleware.AuthMiddleware(logs.AddCompName(context.Background(), "AuthMiddleware"), a.tokenService, a.userRepo)) // 1. 身份认证中间件
|
||||||
authGroup.Use(middleware.AuditLogMiddleware(a.auditService)) // 2. 审计日志中间件
|
authGroup.Use(middleware.AuditLogMiddleware(logs.AddCompName(context.Background(), "AuditLogMiddleware"), a.auditService)) // 2. 审计日志中间件
|
||||||
{
|
{
|
||||||
// 用户相关路由组
|
// 用户相关路由组
|
||||||
userGroup := authGroup.Group("/users")
|
userGroup := authGroup.Group("/users")
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/domain/audit"
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/audit"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuditLogMiddleware 创建一个Echo中间件,用于在请求结束后记录用户操作审计日志。
|
// AuditLogMiddleware 创建一个Echo中间件,用于在请求结束后记录用户操作审计日志。
|
||||||
// 它依赖于控制器通过调用 SendSuccessWithAudit 或 SendErrorWithAudit 在上下文中设置的审计信息。
|
// 它依赖于控制器通过调用 SendSuccessWithAudit 或 SendErrorWithAudit 在上下文中设置的审计信息。
|
||||||
func AuditLogMiddleware(auditService audit.Service) echo.MiddlewareFunc {
|
func AuditLogMiddleware(ctx context.Context, auditService audit.Service) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
|
newCtx := logs.AddFuncName(ctx, c.Request().Context(), "AuditLogMiddleware")
|
||||||
|
|
||||||
// 首先执行请求链中的后续处理程序(即业务控制器)
|
// 首先执行请求链中的后续处理程序(即业务控制器)
|
||||||
err := next(c)
|
err := next(c)
|
||||||
|
|
||||||
@@ -44,6 +49,7 @@ func AuditLogMiddleware(auditService audit.Service) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
// 调用审计服务记录日志(异步)
|
// 调用审计服务记录日志(异步)
|
||||||
auditService.LogAction(
|
auditService.LogAction(
|
||||||
|
newCtx,
|
||||||
user,
|
user,
|
||||||
reqCtx,
|
reqCtx,
|
||||||
actionType,
|
actionType,
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/domain/token"
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/token"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -16,9 +18,11 @@ import (
|
|||||||
|
|
||||||
// AuthMiddleware 创建一个Echo中间件,用于JWT身份验证
|
// AuthMiddleware 创建一个Echo中间件,用于JWT身份验证
|
||||||
// 它依赖于 TokenService 来解析和验证 token,并使用 UserRepository 来获取完整的用户信息
|
// 它依赖于 TokenService 来解析和验证 token,并使用 UserRepository 来获取完整的用户信息
|
||||||
func AuthMiddleware(tokenService token.Service, userRepo repository.UserRepository) echo.MiddlewareFunc {
|
func AuthMiddleware(ctx context.Context, tokenService token.Service, userRepo repository.UserRepository) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
|
reqCtx := logs.AddFuncName(ctx, c.Request().Context(), "AuthMiddleware")
|
||||||
|
|
||||||
// 从 Authorization header 获取 token
|
// 从 Authorization header 获取 token
|
||||||
authHeader := c.Request().Header.Get("Authorization")
|
authHeader := c.Request().Header.Get("Authorization")
|
||||||
if authHeader == "" {
|
if authHeader == "" {
|
||||||
@@ -40,7 +44,7 @@ func AuthMiddleware(tokenService token.Service, userRepo repository.UserReposito
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据 token 中的用户ID,从数据库中获取完整的用户信息
|
// 根据 token 中的用户ID,从数据库中获取完整的用户信息
|
||||||
user, err := userRepo.FindByID(claims.UserID)
|
user, err := userRepo.FindByID(reqCtx, claims.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
// Token有效,但对应的用户已不存在
|
// Token有效,但对应的用户已不存在
|
||||||
|
|||||||
Reference in New Issue
Block a user