签入脚本
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
|
||||
"easygoadmin/internal/consts"
|
||||
"easygoadmin/utility/response"
|
||||
)
|
||||
|
||||
// ============================== 统一响应兜底中间件 ==============================
|
||||
|
||||
// Response 统一响应兜底
|
||||
//
|
||||
// 负责 panic 恢复并输出统一 JSON 错误(前端契约 {code,msg,data}),
|
||||
// 置于跨域之后、认证之前,保证任何环节的 panic 都不会泄漏堆栈到前端。
|
||||
// 同时将请求元信息(IP、UA、方法、URL)写入上下文,供登录日志与操作日志采集。
|
||||
func Response(r *ghttp.Request) {
|
||||
// SVG 静态文件加固:强制附件下载 + nosniff(防内嵌脚本同源执行)
|
||||
if strings.HasSuffix(strings.ToLower(r.URL.Path), ".svg") {
|
||||
r.Response.Header().Set("Content-Disposition", "attachment")
|
||||
r.Response.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
}
|
||||
// 请求元信息(所有路由均需,登录日志依赖)
|
||||
r.SetCtx(consts.WithRequestMeta(r.Context(),
|
||||
realClientIP(r),
|
||||
r.Header.Get("User-Agent"),
|
||||
r.Method,
|
||||
r.URL.String(),
|
||||
))
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
g.Log().Errorf(r.Context(), "panic recovered: %v\n%s", e, debug.Stack())
|
||||
if _, written := response.GetCode(r); written {
|
||||
return // 已写出响应,仅记录
|
||||
}
|
||||
response.WriteWithCode(r,
|
||||
response.Fail(gerror.NewCode(consts.CodeServerError, fmt.Sprintf("服务器内部错误: %v", e))),
|
||||
500)
|
||||
}
|
||||
}()
|
||||
r.Middleware.Next()
|
||||
}
|
||||
Reference in New Issue
Block a user