初始化项目框架,完成部分接口开发
This commit is contained in:
52
internal/middleware/auth.go
Normal file
52
internal/middleware/auth.go
Normal file
@ -0,0 +1,52 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"server/utility/ecode"
|
||||
"server/utility/jwt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
)
|
||||
|
||||
// Auth 是用于权限验证的中间件。
|
||||
//
|
||||
// 它会从请求头中读取 Authorization 字段,验证 JWT Token 的合法性。
|
||||
// 如果请求未携带 Token,则默认赋予 "guest" 权限。
|
||||
// 如果 Token 存在且合法,则将用户信息(userId、permission、jti)注入到请求上下文中。
|
||||
//
|
||||
// Token 应采用 Bearer 方案,例如:
|
||||
//
|
||||
// Authorization: Bearer <token>
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// r *ghttp.Request - 当前的请求对象,由 ghttp 框架自动注入。
|
||||
//
|
||||
// 行为:
|
||||
// - 若无 Token:设定 permission 为 guest,放行请求。
|
||||
// - 若 Token 格式非法或解析失败:终止请求并返回错误。
|
||||
// - 若 Token 合法:将用户信息写入上下文,继续执行下一个中间件或处理函数。
|
||||
func Auth(r *ghttp.Request) {
|
||||
token := r.GetHeader("Authorization")
|
||||
ctx := r.GetCtx()
|
||||
if token == "" {
|
||||
glog.Infof(ctx, "未登录用户访问: %s %s", r.URL.Path, r.Method)
|
||||
r.SetCtxVar("role", "guest")
|
||||
} else {
|
||||
if !strings.HasPrefix(token, "Bearer ") {
|
||||
r.SetError(ecode.InvalidOperation.Sub("invalid_token_format"))
|
||||
return
|
||||
}
|
||||
tokenOut, err := jwt.ParseToken(token)
|
||||
if err != nil {
|
||||
r.SetError(err)
|
||||
return
|
||||
}
|
||||
r.SetCtxVar("id", tokenOut.UserId)
|
||||
r.SetCtxVar("role", tokenOut.Role)
|
||||
r.SetCtxVar("jti", tokenOut.JTI)
|
||||
glog.Infof(ctx, "%s用户Id:%d 访问: %s %s", tokenOut.Role, tokenOut.UserId, r.URL.Path, r.Method)
|
||||
}
|
||||
r.Middleware.Next()
|
||||
}
|
||||
29
internal/middleware/casbin.go
Normal file
29
internal/middleware/casbin.go
Normal file
@ -0,0 +1,29 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"server/utility/ecode"
|
||||
"server/utility/myCasbin"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// Casbin 是用于访问权限控制的中间件。
|
||||
//
|
||||
// 该中间件基于 Casbin 权限控制框架,校验当前用户是否有权访问指定的 URL 和请求方法。
|
||||
// 用户权限从请求上下文中的 "permission" 字段获取,该字段通常由前置中间件(如 Auth)注入。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// r *ghttp.Request - 当前的 HTTP 请求对象,由框架自动传入。
|
||||
//
|
||||
// 行为:
|
||||
// - 如果权限验证未通过:终止请求,返回权限不足的错误(ecode.Denied)。
|
||||
// - 如果权限验证通过:继续执行后续中间件或处理逻辑。
|
||||
func Casbin(r *ghttp.Request) {
|
||||
role := r.GetCtxVar("role").String()
|
||||
if !myCasbin.GetMyCasbin().HasPermission(role, r.URL.Path, r.Method) {
|
||||
r.SetError(ecode.Denied)
|
||||
return
|
||||
}
|
||||
r.Middleware.Next()
|
||||
}
|
||||
14
internal/middleware/exit.go
Normal file
14
internal/middleware/exit.go
Normal file
@ -0,0 +1,14 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
func Exit(r *ghttp.Request, err error) {
|
||||
r.Response.WriteJsonExit(ghttp.DefaultHandlerResponse{
|
||||
Code: gerror.Code(err).Code(),
|
||||
Message: gerror.Code(err).Message(),
|
||||
Data: nil,
|
||||
})
|
||||
}
|
||||
20
internal/middleware/language.go
Normal file
20
internal/middleware/language.go
Normal file
@ -0,0 +1,20 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"server/utility/i18n"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// Language 语言检测中间件
|
||||
// 从请求头或查询参数中检测语言设置,并设置到上下文中
|
||||
func Language(r *ghttp.Request) {
|
||||
// 获取语言设置
|
||||
lang := i18n.GetLanguage(r.GetCtx())
|
||||
|
||||
// 将语言设置到上下文中,供后续使用
|
||||
r.SetCtxVar("language", lang)
|
||||
|
||||
// 继续下一个中间件
|
||||
r.Middleware.Next()
|
||||
}
|
||||
69
internal/middleware/response.go
Normal file
69
internal/middleware/response.go
Normal file
@ -0,0 +1,69 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"server/utility/ecode"
|
||||
"server/utility/i18n"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
func Response(r *ghttp.Request) {
|
||||
r.Middleware.Next()
|
||||
|
||||
if r.Response.BufferLength() > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
msg string
|
||||
err = r.GetError()
|
||||
res = r.GetHandlerResponse()
|
||||
code = gerror.Code(err)
|
||||
ctx = r.GetCtx()
|
||||
)
|
||||
glog.Debug(gctx.New(), "错误", err)
|
||||
if err != nil {
|
||||
if gconv.String(code.Detail()) != "customer" && code.Code() != 51 {
|
||||
msg = ecode.Fail.MessageI18n(ctx)
|
||||
} else if code.Code() == 51 {
|
||||
msg = ecode.Params.MessageI18n(ctx)
|
||||
} else {
|
||||
// 尝试从国际化系统获取消息
|
||||
msg = i18n.T(ctx, code.Message())
|
||||
if msg == code.Message() {
|
||||
// 如果没有找到国际化消息,使用原始消息
|
||||
msg = code.Message()
|
||||
}
|
||||
}
|
||||
} else if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
|
||||
// HTTP状态码错误消息的国际化
|
||||
switch r.Response.Status {
|
||||
case http.StatusNotFound:
|
||||
code = gcode.CodeNotFound
|
||||
msg = i18n.T(ctx, "not_found")
|
||||
case http.StatusForbidden:
|
||||
code = gcode.CodeNotAuthorized
|
||||
msg = i18n.T(ctx, "forbidden")
|
||||
case http.StatusUnauthorized:
|
||||
code = gcode.CodeNotAuthorized
|
||||
msg = i18n.T(ctx, "unauthorized")
|
||||
default:
|
||||
code = gcode.CodeUnknown
|
||||
msg = i18n.T(ctx, "unknown_error")
|
||||
}
|
||||
} else {
|
||||
code = gcode.CodeOK
|
||||
msg = i18n.T(ctx, "success")
|
||||
}
|
||||
r.Response.WriteJson(ghttp.DefaultHandlerResponse{
|
||||
Code: code.Code(),
|
||||
Message: msg,
|
||||
Data: res,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user