go-zero中api服务使用全局拦截器
1.中间件
package apiserver
import (
"context"
"fmt"
"go-weixin/app/usercenter/userrpc/pb/proto/usercenter"
"go-weixin/app/usercenter/userrpc/userrpcclient"
"go-weixin/common/ctxdata"
"net/http"
"regexp"
"strconv"
"time"
mapset "github.com/deckarep/golang-set/v2"
"github.com/zeromicro/go-zero/rest/httpx"
"github.com/zeromicro/x/errors"
"google.golang.org/grpc"
)
type ApiAuthMiddleware struct {
UserRpc userrpcclient.UserCenter
}
func NewApiMiddleware(userRpc userrpcclient.UserCenter) *ApiAuthMiddleware {
return &ApiAuthMiddleware{
UserRpc: userRpc,
}
}
func (m *ApiAuthMiddleware) AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
url := r.URL.Path
uid := ctxdata.GetUidFromCtx(r.Context())
if (url != "/user/login") && (url != "/user/register") && (uid != 1) {
ctx, cannFunc := context.WithTimeout(context.Background(), 5*time.Second)
defer cannFunc()
res, err := m.UserRpc.UserGetPower(ctx, &usercenter.UserGetPowerReq{
Id: uid,
})
if err != nil {
httpx.ErrorCtx(r.Context(), w, errors.New(400, err.Error()))
return
}
powerList := mapset.NewSet[string]()
if len(res.PowerList) > 0 {
for _, power := range res.PowerList {
powerList.Add(power.Url)
}
}
fmt.Println(powerList)
fmt.Printf("auth请求路径: %s \n", url)
if !powerList.Contains(url) {
httpx.ErrorCtx(r.Context(), w, errors.New(404, "没有权限请求此路径"))
return
}
}
next(w, r)
}
}
// rpc-client客户端拦截器
func ClientRpcMiddleware(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
err := invoker(ctx, method, req, reply, cc, opts...)
if err != nil {
errStr := err.Error()
reg := regexp.MustCompile(`code = Code\((?P<code>\d+)\) desc = (?P<msg>.*)`)
res := reg.FindAllStringSubmatch(errStr, 1)
for _, match := range res {
codeStr := match[reg.SubexpIndex("code")]
msg := match[reg.SubexpIndex("msg")]
code, e := strconv.Atoi(codeStr)
if e != nil {
code = 7000
}
err = errors.New(code, msg)
}
return err
}
return nil
}
2. 注册路由
router.go
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.Use(serverCtx.ApiMDLE.AuthMiddleware)
...
...
}