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/v1
    	group:      demo
    	middleware: AuthMiddleware
    )
    service demo-api {
    	@doc "添加"
    	@handler PostDemoHandler
    	post /postDemo (PostDemoReq) returns (Response)
    
    	@doc "分页获取用户"
    	@handler GetUserPageApi
    	get /user/page (GetUserPageReq) returns (UserPageResp)
    }
    
  • 2、使用命令生成文件

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

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

    package middleware
    
    import (
    	"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 middleware
    
    import (
    	"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.Config
    	conf.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 middleware
    
    import (
    	"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: localhost
      Port: 6379
      Pass: ""
      Tls: false
    
  • 4、配置文件中添加配置

    package config
    
    import "github.com/zeromicro/go-zero/rest"
    
    type Config struct {
    	rest.RestConf
    	// 使用redis
    	RedisConfig struct {
    		Host string
    		Port int
    		Pass string
    		Tls  bool
    	}
    }
    
  • 5、定义一个redisDb.go的文件

    package database
    
    import (
    	"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 svc
    
    import (
    	"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.Config
    	AuthMiddleware rest.Middleware
    	RedisDb        *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 middleware
    
    import (
    	"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"))
      

五、参考文件

  • 官方地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/870622.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

漏洞挖掘 | 某系统webpack接口泄露引发的一系列漏洞

信息搜集 这里找到从小穿一条裤子长大的兄弟,要挟他交出来他的统一账号,否则把小时候的照片挂网上,开始某大学的资产搜集,直接hunter搜索此大学域名 看有价值的站点,ok找到下面的站点 未授权敏感信息泄露越权任意用…

docker compose部署rabbitmq集群,并使用haproxy负载均衡

一、创建rabbitmq的data目录 mkdir data mkdir data/rabbit1 mkdir data/rabbit2 mkdir data/rabbit3 二、创建.erlang.cookie文件(集群cookie用) echo "secretcookie" > .erlang.cookie 三、创建haproxy.cfg配置文件 global log stdout fo…

018集——递归函数和for循环对比(从1加到100实例) ——C#学习笔记

本例分别用递归函数和for循环,求出1到100的和: using System;namespace Mytest {class Mytest{static void Main(string[] args){Calculate Myc new Calculate();int YourNumber 100;int Mysum Myc.Xto1(YourNumber);Console.WriteLine("从1加到…

Go-Zero微服务框架下开发接口流程

目录 一:定义api入参和返回值 二:生成入参和返回值文件 三:定义rpc参数和返回值 四:生成返回值和参数 五:定义数据库 六:生成数据库文件 今天我们来讲解下如何在Go-Zero下开发一个api接口的具体流程&…

Android 13 GMS 内置壁纸

如图,原生系统上,设备上的壁纸 显示系统内置壁纸。如果没有添加内置壁纸,就显示默认的壁纸。点击进去就是预览页面 扩展下,默认壁纸在 frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png frameworks/b…

Markdown导出为 Excel文件 Vue3

直接复制到单文件内即可使用 需要用到的插件 xlsx 0.17.5marked 14.0.0file-saver 2.0.5vue 3.4.29 直接SFC单文件内使用 <script setup> import {reactive} from vue; import xlsx from xlsx; import {marked} from marked; import {saveAs} from file-saver;const…

博达网站群管理平台 v6.0使用相关问题解决

1 介绍 最近受人所托&#xff0c;需要用博达网站群管理平台创建一个网站。该平台的内部版本为9.8.2。作为一个能直接从代码创建网站系统的人&#xff0c;初次使用本平台&#xff0c;刚开始感觉摸不着头脑。因为该平台存在的目的&#xff0c;就是让不懂代码的人能快速创建网站&…

Go语言导入gin包

访问https://pkg.go.dev/页面,输入gin 点击README&#xff0c;点击Getting started&#xff0c;点击Getting Gin。 以VSCode通过mod命令导入gin包为例 安装第三方库 go mod init go mod tidy运行成功创建go.mod文件 go get -u github.com/gin-gonic/gin创建Go项目&#xf…

el-image 图片预览时 与 el-table (或avue-crud) 样式冲突 的解决

问题: 解决 <style scoped> ::v-deep(.el-table__cell) {position: static !important; } </style> 后效果

尚品汇-前端调用搜索实现(三十二)

目录&#xff1a; &#xff08;1&#xff09;修改web-all模块 &#xff08;2&#xff09;配置网关 &#xff08;3&#xff09;页面渲染 &#xff08;4&#xff09;面包屑处理 &#xff08;1&#xff09;修改web-all模块 修改pom.xml文件 <dependencies><depende…

手撕C++入门基础

1.C介绍 C课程包括&#xff1a;C语法、STL、高阶数据结构 C参考文档&#xff1a;Reference - C Reference C 参考手册 - cppreference.com cppreference.com C兼容之前学习的C语言 2.C的第一个程序 打印hello world #define _CRT_SECURE_NO_WARNINGS 1 // test.cpp // …

软件测试---接口测试

一、接口及接口测试概念 &#xff08;1&#xff09;接口的类型 &#xff08;2&#xff09;接口测试的概念 &#xff08;3&#xff09;接口测试的原理 &#xff08;4&#xff09;接口测试的特点 &#xff08;5&#xff09;接口测试的实现方式 二、HTTP协议 &#xff08;1&#…

C++:哈希

目录 unordered系列关联式容器 1&#xff1a;unordered_map And unordered_multimap 2&#xff1a;unordered_set And unordered_multiset 3&#xff1a;哈希冲突 4&#xff1a;哈希冲突 5&#xff1a;哈希函数 6&#xff1a;解决哈希冲突 1&#xff1a;闭散列 2&#xf…

Linux高编-进程的概念(1)

目录 1.ps aux 2.top 3.kill -2 进程pid // fork函数 getpid拿自己的进程号 getppid拿父进程号 fork&#xff08;&#xff09;&&fork&#xff08;&#xff09;||fork&#xff08;&#xff09; 父子进程的关系&#xff1a; 僵尸进程&#xff0c;孤儿进程 僵…

招生简章不会设计?这个网站可以供你参考

招生简章是学校与潜在学生之间的第一座桥梁&#xff0c;它的设计直接影响到学校的形象和招生效果。如果你在设计招生简章时感到困惑&#xff0c;不妨参考以下几个要点&#xff0c;让你的招生简章更加吸引人。 1.明确目标受众&#xff1a;在设计招生简章之前&#xff0c;首先要明…

Cesium模型制作,解决Cesium加载glb/GLTF显示太黑不在中心等问题

Cesium模型制作&#xff0c;解决Cesium加载glb/GLTF显示太黑不在中心等问题 QQ可以联系这里&#xff0c;谢谢

关于xilinx的FFTIP的使用和仿真

工具&#xff1a;vivado2018.3&#xff0c;modelsim10.6d 场景&#xff1a;在进行数据进行频谱分析的时候&#xff0c;使用FPGA来完成FFT的计算可以加快数据的计算速度。 下面使用仿真完成DDS产生的数据的FFT以及IFFT。原始数据使用DDSIP产生&#xff0c;通过IP产生的波形数据…

【Linux入门】Linux常见指令

目录 前言 一、Linux基本指令 1.ls指令 2.pwd命令 3.cd 指令 4.touch指令 5.mkdir指令 6.rmdir指令 && rm 指令 7.man指令 8.cp指令 9.mv指令 10.cat 11.date 12.top 13.shutdown-关机 14.重要的几个热键 二、Linux扩展指令 总结 前言 Linux指令是在…

map/set和unordered_map/unordered_set的区别及使用情况

map/set和unordered_map/unordered_set的区别 容器底层数据结构是否有序实现版本复杂度迭代器map/set红黑树有序C98O(logN&#xff09;双向迭代器unordered_map/unordered_set哈希表/散列表无序C11O(1)单向迭代器 unordered_set无序的&#xff08;VS下&#xff09; void uno…

Spring IoCDI(下)—DI的尾声

我们之前学习了控制反转IoC&#xff0c;接下来就开始学习依赖注入DI的细节。 依赖注入是一个过程&#xff0c;是指IoC容器在创建Bean时&#xff0c;去提供运行时所依赖的资源&#xff0c;而资源指的就是对象。我们使用 Autowired 注解&#xff0c;完成依赖注入的操作。简单来说…