go 微服务框架kratos使用中间件的方法

一、中间件的概念

在go语言中,中间件是一种用于处理http请求的开发模式,允许开发人员在请求到达处理程序之前或之后执行特定的操作,如日志记录、身份验证、错误处理等。

中间件通常是一个函数,它接收一个 `http.Handler` 作为参数并返回另一个 `http.Handler`。

go源码中 Handler 的定义如下:

type Handler interface {ServeHTTP(ResponseWriter, *Request)
}

二、go原生http中使用中间件的方法

  • 使用方法:

1、创建中间件函数,输入参数 http.Handler,输出参数 http.Handler

2、将处理器函数作为参数传入上述中间件函数

3、运用 Handle(pattern string, handler Handler) 等函数将中间件函数绑定到请求路由中

  • 代码示例:
package mainimport ("fmt""log""net/http"
)// 日志记录中间件
func loggingMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {log.Printf("请求处理之前   Request URI: %s\n", r.RequestURI)next.ServeHTTP(w, r)log.Printf("处理程序之后进行的操作...\n")})
}// handler 处理函数
func SayHello(w http.ResponseWriter, r *http.Request) {fmt.Println("Hello world")
}func main() {//创建一个 HTTP 请求路由器mux := http.NewServeMux()// 使用日志记录中间件mux.Handle("/index", loggingMiddleware(http.HandlerFunc(SayHello)))//启动服务,使用创建的 ServeMuxhttp.ListenAndServe(":8081", mux)
}
  • 运行效果:

三、go微服务框架Kratos使用中间件的方法

kratos介绍中间件的官网地址:概览 | Kratos

1、内置中间件使用方法

①通过 Middleware(m ...middleware.Middleware) ServerOption 添加所需的中间件

②将上述由中间件组成的 ServerOption 添加到 []http.ServerOption 中

③通过函数 NewServer(opts ...ServerOption) *Server 创建 httpServer

  • 代码示例:
func NewHTTPServer(c *conf.Server, logger log.Logger, blog *service.BlogService) *http.Server {opts := []http.ServerOption{http.Middleware(//使用kratos内置中间件recovery.Recovery(),tracing.Server(),logging.Server(logger),validate.Validator(),),}if c.Http.Network != "" {opts = append(opts, http.Network(c.Http.Network))}if c.Http.Addr != "" {opts = append(opts, http.Address(c.Http.Addr))}if c.Http.Timeout != nil {opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))}//创建 httpServer srv := http.NewServer(opts...)v1.RegisterBlogServiceHTTPServer(srv, blog)return srv
}

2、自定义中间件使用方法

①实现 middleware.Middleware 接口,其定义如下:

// Handler defines the handler invoked by Middleware.
type Handler func(ctx context.Context, req interface{}) (interface{}, error)// Middleware is HTTP/gRPC transport middleware.
type Middleware func(Handler) Handler

中间件中您可以使用 tr, ok := transport.FromServerContext(ctx) 获得 Transporter 实例以便访问接口相关的元信息。

②像添加内置中间件一样,将自定义中间件添加到 http.Middleware 和 []http.ServerOption 中

③通过函数 NewServer(opts ...ServerOption) *Server 创建 httpServer

  • 代码示例:
// auth.go 单元
//自定义 JWT 认证中间件
func JWTAuth(jwtSecret string) middleware.Middleware {return func(handler middleware.Handler) middleware.Handler {return func(ctx context.Context, req interface{}) (reply interface{}, err error) {if tr, ok := transport.FromServerContext(ctx); ok {tokenString := tr.RequestHeader().Get("authorization")spew.Dump(tokenString)//token, err := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {// Don't forget to validate the alg is what you expect:if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])}// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")return []byte(jwtSecret), nil})if err != nil {log.Fatal(err)}if claims, ok := token.Claims.(jwt.MapClaims); ok {fmt.Println(claims["iss"], claims["exp"])//fmt.Println(claims.Issuer, claims.ExpiresAt)} else {fmt.Println(err)}}return handler(ctx, req)}}
}// server/http.go 单元
func NewHTTPServer(c *conf.Server, confAuth *conf.Auth, logger log.Logger, blog *service.BlogService) *http.Server {opts := []http.ServerOption{http.Middleware(//自定义中间件 JWTAuthauth.JWTAuth(confAuth.JwtSecrect),),}if c.Http.Network != "" {opts = append(opts, http.Network(c.Http.Network))}if c.Http.Addr != "" {opts = append(opts, http.Address(c.Http.Addr))}if c.Http.Timeout != nil {opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))}//创建 httpServer srv := http.NewServer(opts...)v1.RegisterBlogServiceHTTPServer(srv, blog)return srv
}

3、为特定路由定制中间件的使用方法

  • 使用方法:

对特定路由定制中间件:

server: selector.Server(ms...)

client: selector.Client(ms...)

  • 代码示例:

// server/http.go 单元
// 添加验证白名单
func NewWhiteListMatcher() selector.MatchFunc {whiteList := make(map[string]struct{})whiteList["/blog.api.v1.Account/Login"] = struct{}{}whiteList["/blog.api.v1.Account/Register"] = struct{}{}return func(ctx context.Context, operation string) bool {if _, ok := whiteList[operation]; ok {return false}return true}
}// server/http.go 单元
func NewHTTPServer(c *conf.Server, confAuth *conf.Auth, logger log.Logger, blog *service.BlogService) *http.Server {opts := []http.ServerOption{http.Middleware(//自定义中间件 JWTAuthselector.Server(auth.JWTAuth(confAuth.JwtSecrect)).Match(NewWhiteListMatcher()).Build(),),}if c.Http.Network != "" {opts = append(opts, http.Network(c.Http.Network))}if c.Http.Addr != "" {opts = append(opts, http.Address(c.Http.Addr))}if c.Http.Timeout != nil {opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))}//创建 httpServer srv := http.NewServer(opts...)v1.RegisterBlogServiceHTTPServer(srv, blog)return srv
}

注意: 定制中间件是通过 operation 匹配,并不是 http 本身的路由!!!

gRPC path 的拼接规则为 /包名.服务名/方法名(/package.Service/Method)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ardupilot开源代码之Rover上路 - 后续4

Ardupilot开源代码之Rover上路 - 后续4 1. 源由2. 深度配置2.1 设置倒车按钮2.1.1 前进2.1.2 倒退 2.2 MP无法连接ESP82662.3 最小油门校准 3. 遗留&后续3.1 高精度编码器问题3.2 OV5647 720P30FPS 马赛克问题 4. 参考资料 1. 源由 开源项目最主要的问题就是所有配置是开放…

信息安全从运维到运营:CISAW安全运维方向

随着数据中心规模扩大,安全运维内生需要逐渐向安全运营进化,统一安全理念,提高服务意识,提升专业能力。安全运营是对安全运维的继承式发展,而不是颠覆,意味着以业务发展为基础,以事件核查为线索…

【gradle】MAC下用gradle构建部署springboot项目

MAC下用gradle构建部署springboot项目 前言下载安装配置gradle下载安装下载可能出现的问题 (zsh: command not found: brew) 配置环境变量配置国内下载源全局配置单个项目配置 通过idea构建项目构建后的项目结构 小结延伸 前言 好久以前就听说gradle了&…

RAG概述(一):RAG架构的演进

目录 概述 RAG核心步骤 Indexing索引 Retrieval检索 Generation生成​​​​​​​ Native RAG Advanced RAG Modular RAG 参考 概述 RAG:Retrieval-Augmented Generation 检索增强生成。 RAG通过结合LLMs的内在知识和外部数据库的非参数化数据&#xff…

与MySQL的初相遇

🌎初识MySQL 注:本文SQL语句只为了验证猜想,不会也不要紧。 文章目录: MySql开端 认识数据库       什么是数据库       主流数据库       MySQL的本质 MySQL基础使用       连接mysql服务器     …

自动化您的任务——crewAI 初学者教程

今天,我写这篇文章是为了分享您开始使用一个非常流行的多智能体框架所需了解的所有信息:crewAI。 我将在这里或那里跳过一些内容,使本教程成为一个精炼的教程,概述帮助您入门的关键概念和要点 今天,我写这篇文章是为了…

easy-rule规则引擎使用

简介 轻量级的规则引擎&#xff0c;易于学习的api 简单来说&#xff0c;规则引擎就是一个函数&#xff1a;yf(x1,x2,…,xn) 将业务代码和业务规则分离&#xff0c;解耦业务决策和业务代码的绑定关系 入门示例 依赖引入 <dependency><groupId>org.jeasy</grou…

页面<html>上多了一个滚动条,定位发现是<body>里面多了一个id为trans-tooltip的div

现象分析&#xff1a; 页面根标签html多了一个滚动条&#xff0c;发现body里面多了一个id为trans-tooltip的div&#xff0c;虽然width为0&#xff0c;height为0&#xff0c;但是其子元素还是有高度&#xff0c;占据了空间&#xff0c;最终导致了滚动条&#xff1b; 根本原因&…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

Java面试题--JVM大厂篇(1-10)

引言&#xff1a; 在这个信息时代&#xff0c;对于准备进入大厂工作的朋友们来说&#xff0c;对于JVM&#xff08;Java虚拟机&#xff09;的掌握是面试中的一项重要内容。下面是一些精选的JVM面试题&#xff0c;希望对大家能有所帮助。 正文&#xff1a; 1. JVM有哪几种垃圾收…

[CISCN2024]-PWN:gostack解析(go语言程序,syscall)

查看保护 ida比较复杂&#xff0c;建议动调配合静态分析程序运行 这里函数返回不用leave和ret&#xff0c;而是利用add rsp和ret&#xff0c;所以要动调查看到底要覆盖哪里。 完整exp&#xff1a; from pwn import* pprocess(./gostack) syscall0x4616c9 pop_rax0x40f984 po…

GB报文中的Cseq值的注意点

一、 问题现象 【问题现象】NVR使用GB接三方平台发现倍速回放时&#xff0c; 【现场拓扑】现场拓扑如下 &#xff08;1&#xff09; NVR侧使用家用宽带的方式&#xff0c;通过国标跨公网接入三方平台。 图1.1&#xff1a;网络拓扑 二、 抓包分析 INVITE sip:420000004013200…

OpenAI安全系统负责人:从头构建视频生成扩散模型

作者 | Lilian Weng OneFlow编译 翻译&#xff5c;杨婷、宛子琳、张雪聃 题图由SiliconFlow MaaS平台生成 过去几年&#xff0c;扩散模型&#xff08;Diffusion models&#xff09;在图像合成领域取得了显著成效。目前&#xff0c;研究界已开始尝试更具挑战性的任务——将该技术…

深度学习Day-18:ResNet50V2算法实战与解析

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a; 根据本文Tensorflow代码&#xff0c;编写对应的Pytorch代码了解ResNetV2与ResNetV的区别 一、 基础…

【实战JVM】-基础篇-03-Java内存结构

【实战JVM】-基础篇-03-Java内存结构 1 运行时数据区1.1 总览1.2 程序计数器1.2.1 是否会内存溢出 1.3 java虚拟机栈1.3.1 栈帧的组成1.3.1.1 局部变量表1.3.1.2 操作数栈1.3.1.3 帧数据1.3.1.3.1 动态链接1.3.1.3.2 方法出口1.3.1.3.3 异常表 1.3.2 是否会内存溢出1.3.3 设置虚…

【神经网络结构可视化】使用 Visualkeras 可视化 Keras / TensorFlow 神经网络结构

文章目录 Visualkeras介绍下载安装代码示例1、导入必要的库2、创建VGG16神经网络模型3、可视化神经网络结构4、完整代码5、使用教程 可视化自己创建的神经网络结构1、导入要的库2、创建自己的神经网络模型3、可视化神经网络结构图4、完整代码 Visualkeras介绍 Visualkeras是一…

C++代码错误解决1(函数模板)

1、代码如下 //示例函数模板的使用 #include <iostream> #include <string> using namespace std; template <typename T>//函数模板 T max(T a,T b) {return a>b?a:b; } int main() {int a,b;cout<<"input two integers to a&b:"…

【微机原理及接口技术】可编程并行接口芯片8255A

【微机原理及接口技术】可编程并行接口芯片8255A 文章目录 【微机原理及接口技术】可编程并行接口芯片8255A前言一、8255A的内部结构和引脚1.与外设接口&#xff08;数据端口&#xff09;2.与处理器接口 二、8255A的工作方式三、8255A的编程1. 写入方式控制字&#xff1a;控制字…

从0开始回顾ElasticSearch

1 elasticsearch概述 1.1 elasticsearch简介 官网: https://www.elastic.co/ ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的…

【动手学强化学习】第 6 章 Dyna-Q 算法知识点总结

【动手学强化学习】第 6 章 Dyna-Q 算法知识点总结 本章知识点基于模型的强化学习与无模型的强化学习方法简介无模型的强化学习方法基于模型的强化学习方法 强化学习算法的评价指标Dyna-Q算法Dyna-Q 算法的具体流程Dyna-Q 代码实践 本章知识点 基于模型的强化学习与无模型的强…