当前位置: 首页 > 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"))
      

五、参考文件

  • 官方地址

相关文章:

go-zero中间件的使用

一、自定义中间件 1、在api中在服务中定义一个中间件,名字随便取 type PostDemoReq {Name string json:"name" validate:"required" // 姓名Age int64 json:"age" validate:"required,gte1,lte130" // 年龄// optional 表示可选,omi…...

六、ESP32-S3上使用MicroPython点亮WS2812智能LED灯珠并通过web控制改变灯珠颜色优化超时和线程

实现通过ESP32S3连接Wi-Fi并使用Web页面控制WS2812灯珠的颜色,可以使用ESP32的WebServer库来创建一个简单的Web界面。通过这个界面,可以动态地控制灯珠的显示效果。 针对 五、ESP32-S3上使用MicroPython点亮WS2812智能LED灯珠并通过web控制改变灯珠颜色…...

(el-Time-Picker)操作(不使用 ts):Element-plus 中 TimePicker 组件的使用及输出想要时间格式需求的解决过程

Ⅰ、Element-plus 提供的 TimePicker 时间选择器组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 TimePicker 组件情况&#xff1a; 其一、Element-ui 自提供的 TimePicker 代码情况为(示例的代码)&#xff1a; // Element-plus 提供的组件代码: <template>…...

UIAbility组件基础(一)

一、概述 UIAbility组件是一种包含UI的应用组件&#xff0c;主要用于和用户交互。UIAbility组件是系统调度的基本单元&#xff0c;为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。 U…...

神经网络的数学原理

前言:Hello大家好,我是小哥谈。人工智能技术的发展与成功应用已经成为21世纪科技领域最大的新现象。然而,科学地理解人工智能原理已经超出了现有科学体系的范畴。显然,人工智能是人类科学技术发展的必然结果,人工智能科学也将是人类科学进步与发展必然实现的目标🌈 …...

Java设计模式-抽象工厂模式-一次性理解透

1. 抽象工厂模式简介 抽象工厂设计模式是创建型模式之一。抽象工厂模式与工厂模式几乎相似&#xff0c;只是它更像工厂中的工厂。 如果您熟悉Java 中的工厂设计模式&#xff0c;或看过上一篇我写的“java简单工厂模式”&#xff0c;您会注意到我们有一个工厂类。此工厂类根据…...

day16-测试自动化之selenium的PO模式

一、PO模式介绍 PO&#xff08;Page Object&#xff09;模式是一种在自动化测试中常用的设计模式&#xff0c;将页面的每个元素封装成一个对象&#xff0c;通过操作对象来进行页面的交互。 一般分为六个版本&#xff0c;现在大部分企业都用的V4版本&#xff0c;三层结构…...

Springboot+freemarker大段文本内容动态修改输出,所见即所得

场景&#xff1a;给领导导出数据时&#xff0c;需要给出一个针对专业名词的解释说明&#xff0c;因此会存在有大批量的、大段的文本内容。如果直接写在代码里面&#xff0c;没啥大问题&#xff0c;但是大量的拼接替换、格式样式、后续修改维护等&#xff0c;都不是很方便。如果…...

Kali Linux网络问题解决与静态IP配置技巧

很多用户在使用 Kali Linux 时会遇到无法联网的问题&#xff0c;尤其是在 VMware 虚拟机中。这种情况相当常见&#xff0c;一般都是没有配置DNS服务器或者网卡配置文件的IP和虚拟网络编辑器的IP不一致所导致的&#xff0c;下面我们将探讨如何在 Kali Linux 中配置 DNS 服务和设…...

网络状态码-经验笔记

网络状态码-经验笔记 引言 在网络通信中&#xff0c;HTTP&#xff08;Hypertext Transfer Protocol&#xff09;状态码是服务器向客户端&#xff08;通常是Web浏览器&#xff09;发送响应时所包含的重要信息之一。 这些状态码指示了客户端请求的结果。 了解并正确使用这些状态…...

c++ 实现 actor 框架

服务端&#xff1a;https://github.com/xukeawsl/coro_actor 客户端&#xff1a;https://github.com/xukeawsl/coro_actor_client...

应对猫咪掉毛挑战,希喂、小米热门宠物空气净化器实测功效PK

随着养宠人群的增多&#xff0c;铲屎官们的需求日益增长&#xff0c;市场上出现了很多品牌的宠物空气净化器。然而&#xff0c;产品质量参差不齐&#xff0c;给消费者选择带来不少困难。劣质宠物空气净化器不仅无法有效去除宠物毛发、皮屑、异味及空气中的有害微粒&#xff0c;…...

0002 保险会计及其特殊性

保险会计是将会计理论专门应用于保险公司的专业会计领域&#xff0c;它是会计学的一个重要分支。作为一个分支&#xff0c;保险会计具有独特的特性&#xff0c;这些特性主要表现在以下几个方面&#xff1a; 产品的无形性&#xff1a;保险产品本质上是一种无形的商品&#xff0c…...

ChatTTS:终极文本转语音工具,支持API!

ChatTTS&#xff1a;终极文本转语音工具&#xff0c;支持API&#xff01; 文本转语音&#xff08;TTS&#xff09;系统的发展已经取得了长足的进步。从最初的机械化、平坦的声音&#xff0c;到如今听起来令人惊讶的人声&#xff0c;ChatTTS作为这一领域的新成员&#xff0c;旨…...

VUE和Element Plus

1.VUE 1.下载和配置环境 使用vue编程&#xff0c;我们需要使用到的编程软件是vs code&#xff0c;还需要使用node.js&#xff0c;这个的作用就类似于JDK&#xff0c;当我们都下载好之后&#xff0c;winR键打开命令提示符&#xff0c;我们在这里可以查看版本&#xff0c; npm…...

Python学习笔记(五)

""" 演示tuple元组的定义和操作 """# 元组一旦定义完成&#xff0c;就不可修改 # 定义元组 # t1 (1, "Hello", True) # t2 () # 定义空元组 # t3 tuple() #定义空元组 # print(f"t1的类型是&#xff1a;{type(t1)}, 内容是&…...

Linux企业级应用(一)构建企业级Linux应用平台:全面指南

文章目录 构建企业级Linux应用平台&#xff1a;全面指南前言1. Linux企业级应用简介2. 构建企业级网站应用平台使用LNMP架构构建Web服务器部署MySQL数据库主从复制与读写分离 3. 实施虚拟化技术部署KVM虚拟化平台使用LVS和Keepalived实现负载均衡与高可用性 4. 文件系统与分布式…...

LeetCode112 路径总和

前言 题目&#xff1a; 112. 路径总和 文档&#xff1a; 代码随想录——路径总和 编程语言&#xff1a; C 解题状态&#xff1a; 成功解答&#xff01; 思路 比较简单的一个思路是遍历所有的路径&#xff0c;求和后再查找目标值。但是&#xff0c;最好的方法是一边遍历&#x…...

TI AWR1843 毫米波雷达实物展示

引言 随着自动驾驶、工业自动化以及智能交通系统的快速发展&#xff0c;雷达传感器在现代科技中的重要性日益提升。毫米波雷达凭借其高精度测距、抗干扰能力强等特点&#xff0c;逐渐成为各类感知系统中的关键技术。德州仪器&#xff08;TI&#xff09;推出的 AWR1843 毫米波雷…...

前端JS总结(下)之事件操作

目录 前言 事件基础 事件的三部分&#xff1a; 常见的事件&#xff1a; 鼠标事件&#xff1a; 键盘事件&#xff1a; 表单事件&#xff1a; onfocus和onblur&#xff1a;获取焦点和失去焦点 onselect&#xff1a;选中单行文本框/多行文本框中的内容 onchange&#xff…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...

OCC笔记:TDF_Label中有多个相同类型属性

注&#xff1a;OCCT版本&#xff1a;7.9.1 TDF_Label中有多个相同类型的属性的方案 OCAF imposes the restriction that only one attribute type may be allocated to one label. It is necessary to take into account the design of the application data tree. For exampl…...