当前位置: 首页 > news >正文

go-zero中间件的使用

一、自定义中间件

  • 1、在api中在服务中定义一个中间件,名字随便取

    type PostDemoReq {Name string `json:"name" validate:"required"` // 姓名Age  int64  `json:"age" validate:"required,gte=1,lte=130"` // 年龄// optional 表示可选,omitempty如果为空的时候不走后面Mobile         string `json:"mobile,optional" validate:"omitempty,checkMobile"` // 手机号码Email          string `json:"email,optional" validate:"omitempty,checkEmail"` // 邮箱地址Date           string `json:"date" validate:"omitempty,checkDate,checkAfterDate"` // 时间Password       string `json:"password" validate:"required"` // 密码ConfimPassword string `json:"confimPassword" validate:"eqfield=Password"` // 确认密码
    }// 一般返回
    type Response {Name string `json:"name"`Age  int64  `json:"age"`
    }// 分页显示的
    type UserPageResp {Data       []Response `json:"data"` // 数据Total      int64      `json:"total"` // 总条数PageSize   int64      `json:"pageSize"` // 当前条数PageNumber int64      `json:"pageNumber"` // 当前页数
    }type GetUserPageReq {PageNumber int64 `query:"pageNumber"`PageSize   int64 `query:"pageSize"`
    }@server (prefix:     demo/v1group:      demomiddleware: AuthMiddleware
    )
    service demo-api {@doc "添加"@handler PostDemoHandlerpost /postDemo (PostDemoReq) returns (Response)@doc "分页获取用户"@handler GetUserPageApiget /user/page (GetUserPageReq) returns (UserPageResp)
    }
    
  • 2、使用命令生成文件

    goctl api go -api *.api -dir . --style=gozero
    
  • 3、查看路由中是否使用了中间件,还生成了中间件文件

  • 4、在中间件中补充内容

    package middlewareimport ("github.com/zeromicro/go-zero/core/logx""net/http"
    )type AuthMiddleware struct {
    }func NewAuthMiddleware() *AuthMiddleware {return &AuthMiddleware{}
    }func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("请求之前") // 填充逻辑next(w, r)logx.Info("请求之后")}
    }
    
  • 5、请求日志输出

    在这里插入图片描述

二、全局中间件

  • 1、上面的方式只能在使用路由的时候才生效

  • 2、在路由中取消中间件

  • 3、自定义中间件

    package middlewareimport ("github.com/zeromicro/go-zero/core/logx""net/http"
    )func LogMiddleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("请求前...")next(w, r)logx.Info("请求后....")}
    }
    
  • 4、在启动文件中加入自定义中间件

    func main() {flag.Parse()var c config.Configconf.MustLoad(*configFile, &c)server := rest.MustNewServer(c.RestConf)defer server.Stop()ctx := svc.NewServiceContext(c)handler.RegisterHandlers(server, ctx)// 全局中间件server.Use(middleware.LogMiddleware)fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)server.Start()
    }
    

三、自定义跨域全局中间件

  • 1、创建中间件

    package middlewareimport ("net/http"
    )func CorsMiddleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {//指定允许其他域名访问//ctx.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:8080")w.Header().Set("Access-Control-Allow-Origin", "*") //跨域:CORS(跨来源资源共享)策略//预检结果缓存时间w.Header().Set("Access-Control-Max-Age", "86400")//允许的请求类型(GET,POST等)w.Header().Set("Access-Control-Allow-Methods", "*")//允许的请求头字段w.Header().Set("Access-Control-Allow-Headers", "*")//是否允许后续请求携带认证信息(cookies),该值只能是true,否则不返回w.Header().Set("Access-Control-Allow-Credentials", "true")if r.Method == http.MethodOptions {w.WriteHeader(http.StatusOK)return}next(w, r)}
    }
    
  • 2、使用中间件

    // 全局中间件
    server.Use(middleware.LogMiddleware)
    server.Use(middleware.CorsMiddleware)
    

四、自定义Auth鉴权中间件

  • 1、这里不使用jwt的方式,采用登录后自己根据规则生成唯一识别的存到redis中,jwt的方式可以自己网上搜索

  • 2、项目中安装redis

    github.com/go-redis/redis/v8
    
  • 3、配置文件中写上配置

    Name: demo-api
    Host: 0.0.0.0
    Port: 8888# redis配置
    RedisConfig:Host: localhostPort: 6379Pass: ""Tls: false
    
  • 4、配置文件中添加配置

    package configimport "github.com/zeromicro/go-zero/rest"type Config struct {rest.RestConf// 使用redisRedisConfig struct {Host stringPort intPass stringTls  bool}
    }
    
  • 5、定义一个redisDb.go的文件

    package databaseimport ("fmt""github.com/go-redis/redis/v8"
    )func NewRedisDB(host, pass string, port int) *redis.Client {redisDb := redis.NewClient(&redis.Options{Addr:     fmt.Sprintf("%s:%d", host, port),Password: pass,DB:       0,})return redisDb
    }
    
  • 6、在internal\svc\servicecontext.go中注册redis

    package svcimport ("github.com/go-redis/redis/v8""github.com/zeromicro/go-zero/rest""go_zero_demo06/internal/config""go_zero_demo06/internal/database""go_zero_demo06/internal/middleware"
    )type ServiceContext struct {Config         config.ConfigAuthMiddleware rest.MiddlewareRedisDb        *redis.Client
    }func NewServiceContext(c config.Config) *ServiceContext {redisDb := database.NewRedisDB(c.RedisConfig.Host, c.RedisConfig.Pass, c.RedisConfig.Port)return &ServiceContext{Config:         c,AuthMiddleware: middleware.NewAuthMiddleware(redisDb).Handle,RedisDb:        redisDb,}
    }
    
  • 7、中间件中修改

    package middlewareimport ("context""fmt""github.com/go-redis/redis/v8""net/http"
    )type AuthMiddleware struct {RedisDb *redis.Client
    }func NewAuthMiddleware(redisDb *redis.Client) *AuthMiddleware {return &AuthMiddleware{RedisDb: redisDb,}
    }func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {token := r.Header.Get("token")fmt.Println("请求的token", token)if token == "" {w.WriteHeader(http.StatusAccepted)w.Write([]byte("请登录"))return}get := m.RedisDb.Get(r.Context(), token)fmt.Println(get, "redis中读取的数据")// 下面的模拟将从token中读取到的数据塞到上下文中ctx := context.WithValue(r.Context(), "accountId", "1")ctx = context.WithValue(ctx, "username", "admin")next(w, r.WithContext(ctx))}
    }
    
  • 8、请求结果

    在这里插入图片描述

  • 9、在别的地方读取上下文中传递的参数

    • handler

      fmt.Println("获取请求头传递的数据", r.Context().Value("accountId"))
      fmt.Println("获取请求头传递的数据", r.Context().Value("username"))
      
    • logic

      fmt.Println("获取请求头传递的数据1", l.ctx.Value("accountId"))
      fmt.Println("获取请求头传递的数据2", l.ctx.Value("username"))
      

五、参考文件

  • 官方地址
http://www.lryc.cn/news/423980.html

相关文章:

  • 六、ESP32-S3上使用MicroPython点亮WS2812智能LED灯珠并通过web控制改变灯珠颜色优化超时和线程
  • (el-Time-Picker)操作(不使用 ts):Element-plus 中 TimePicker 组件的使用及输出想要时间格式需求的解决过程
  • UIAbility组件基础(一)
  • 神经网络的数学原理
  • Java设计模式-抽象工厂模式-一次性理解透
  • day16-测试自动化之selenium的PO模式
  • Springboot+freemarker大段文本内容动态修改输出,所见即所得
  • Kali Linux网络问题解决与静态IP配置技巧
  • 网络状态码-经验笔记
  • c++ 实现 actor 框架
  • 应对猫咪掉毛挑战,希喂、小米热门宠物空气净化器实测功效PK
  • 0002 保险会计及其特殊性
  • ChatTTS:终极文本转语音工具,支持API!
  • VUE和Element Plus
  • Python学习笔记(五)
  • Linux企业级应用(一)构建企业级Linux应用平台:全面指南
  • LeetCode112 路径总和
  • TI AWR1843 毫米波雷达实物展示
  • 前端JS总结(下)之事件操作
  • 如何妙用哈希表来优化遍历查找过程?刷题感悟总结,c++实现
  • 【设计模式】漫谈设计模式
  • 第N5周:Pytorch文本分类入门
  • SpringBoot 自定义 starter
  • TDengine Invalid data format 问题定位
  • Spring Boot 使用 MongoDB 教程
  • Python办公自动化:使用openpyxl 创建与保存 Excel 工作簿
  • 【张】#11 Union 共用体
  • Xcode 在原生集成flutter项目
  • ES6的promise
  • 轻松找回:如何在PostgreSQL 16中重置忘记的数据库密码