【gRPC-gateway】auth-通过拦截器从上下文中提取元数据用于认证,与从http header转发待认证数据到上下文进行验证,go案例
从grpc上下文中提取元数据用于认证 案例
interceptor.go
package serverimport ("context""errors""google.golang.org/grpc""google.golang.org/grpc/metadata""strings"
)// UnaryInterceptor 是一个 unary RPC 的拦截器,用于在处理请求前进行身份认证。
// 参数:
//
// ctx - 上下文,用于传递请求相关的元数据。
// req - 请求的数据。
// info - 包含被拦截的 RPC 方法的信息。
// handler - 下游的处理器,用于执行实际的 RPC 方法。
//
// 返回值:
//
// 响应数据和可能的错误。
func UnaryInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {// 在执行实际的处理函数前进行身份认证。err = auth(ctx)if err != nil {return nil, err}// 身份认证通过后,调用实际的处理函数。return handler(ctx, req)
}// StreamInterceptor 是一个 streaming RPC 的拦截器,用于在处理请求前进行身份认证。
// 参数:
//
// srv - 服务器的实现。
// ss - 服务器流,用于读取请求和写入响应。
// info - 包含被拦截的 streaming RPC 方法的信息。
// handler - 下游的处理器,用于执行实际的 streaming RPC 方法。
//
// 返回值:
//
// 可能的错误。
func StreamInterceptor(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {// 在执行实际的处理函数前进行身份认证。err := auth(ss.Context())if err != nil {return err}// 身份认证通过后,调用实际的处理函数。return handler(srv, ss)
}// auth 函数用于执行身份认证逻辑。
// 参数:
//
// ctx - 上下文,用于传递请求相关的元数据。
//
// 返回值:
//
// 如果身份认证失败,返回错误;否则返回 nil。
func auth(ctx context.Context) error {// 从上下文中提取元数据,用于身份认证。md, ok := metadata.FromIncomingContext(ctx)if !ok {return errors.New("元数据获取失败,身份认证失败")}// 检查元数据中是否包含认证信息。authorization := md["authorization"]if len(authorization) < 1 {return errors.New("元数据获取失败,身份认证失败")}// 提取并验证 token。token := strings.TrimPrefix(authorization[0], "Bearer ")if token != bearerToken {return errors.New("身份认证失败")}// 身份认证成功。return nil
}// bearerToken 是用于身份认证的密钥。
var bearerToken = "asdfgh"
main.go
s := grpc.NewServer(grpc.UnaryInterceptor(server.UnaryInterceptor), grpc.StreamInterceptor(server.StreamInterceptor))

从http header转发到grpc上下文进行认证 案例
- 因为gateway负责,将远端http请求转为gRPC从而与grpc服务器通信,所以应该在gateway中处理http header,使其中需要的部分放入grpc上下文中

通过在runtime.NewServeMux(inComingOpt)中添加处理函数inComingOpt可以解决
可以看到NewServeMux还支持很多操作


gateway.go
package gatewayimport ("context""flag""github.com/grpc-ecosystem/grpc-gateway/v2/runtime"gw "golang19-grpc-gateway/user/proto""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""net/http"
)var (// grpc服务器端点grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:50051", "gRPC server endpoint")
)// Run 启动一个 HTTP 服务器,用于将 HTTP 请求转发到 gRPC 服务器。
// 该函数配置了一个 HTTP 多路复用器以处理不同的 HTTP 路径,并将这些路径与 gRPC 方法关联起来。
// 它还设置了一个不安全的 gRPC 连接选项,仅适用于开发环境。
// 返回值: 如果 HTTP 服务器启动失败或在处理请求时遇到错误,则返回错误。
func Run() error {// 初始化一个上下文对象,用于取消操作和传递请求范围的值。ctx := context.Background()// 创建一个可取消的上下文,以便在函数退出时取消可能的挂起操作。ctx, cancel := context.WithCancel(ctx)// 确保在函数退出时取消上下文。defer cancel()// inComingOpt 配置了一个处理传入的http请求头的选项// 该选项使用一个函数来检查和转换请求头的键// 该匹配器函数决定哪些传入的HTTP头应该被传递给gRPC上下文,以及是否应该修改这些头的键。inComingOpt := runtime.WithIncomingHeaderMatcher(func(s string) (string, bool) {// 如果matcher返回true,则该标头将传递给gRPC上下文。要在传递给gRPC上下文之前转换标头,匹配器应返回修改后的标头。switch s {// 对于"Service-Authorization"头,将其转换为"service-authorization"并传递给gRPC上下文。case "Service-Authorization":return "authorization", true// 不修改请求头的键,不传递给上下文default:return "", false}})// 创建一个 HTTP 处理多路复用器,用于将 HTTP 请求分发到不同的处理程序。mux := runtime.NewServeMux(inComingOpt)// 为 "/upload" 路径添加一个处理程序,处理 POST 请求。mux.HandlePath("POST", "/upload", uploadHandler)// 配置一个不安全的 gRPC 连接选项,这仅适用于开发环境。opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}// 将 gRPC 方法映射为 HTTP 请求,使 HTTP 客户端可以与 gRPC 服务器通信。err := gw.RegisterUserHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)// 如果注册处理程序时发生错误,返回该错误。if err != nil {return err}// 启动 HTTP 服务器,监听端口 8081,使用配置好的多路复用器处理请求。return http.ListenAndServe(":8081", mux)
}
这样改造后,无论是验证上下文中指定数据,还是验证请求头中的数据,只需要保持提取后,重新指定的待验证的key相同就可同时实现

结果演示
既可以验证authorization

也可以验证headers

https://github.com/0voice
相关文章:
【gRPC-gateway】auth-通过拦截器从上下文中提取元数据用于认证,与从http header转发待认证数据到上下文进行验证,go案例
从grpc上下文中提取元数据用于认证 案例 interceptor.go package serverimport ("context""errors""google.golang.org/grpc""google.golang.org/grpc/metadata""strings" )// UnaryInterceptor 是一个 unary RPC 的拦截器…...
Sass基础知识以及常用知识整理
Sass基础知识以及常用知识整理 一、CSS 功能拓展 注意:>、 、和~的区分 1.1 嵌套规则 Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,例如: #main p {color: #00ff00;width: 97%;…...
Redis 内存回收机制
Redis 是一个基于内存的键值存储系统,为了避免内存耗尽,Redis 提供了多种内存回收机制。以下是 Redis 内存回收的主要方式: 1. 过期键删除 Redis 支持为键设置过期时间,过期后会自动删除键以释放内存。 1.1 设置过期时间 SET key…...
docker安装mongo,导入、导出数据
1、docker安装mongo docker pull mongo docker run -d -p 27017:27017 --name mongodb mongodocker update mongodb --restartalways ## 开机自启动-d:表示以后台模式运行容器。 -p 27017:27017:将容器内部的 MongoDB 默认端口 27017 映射到宿主机的 27…...
Excel常用操作
Excel常用操作 学习资源 37_电子表格处理考点精讲_设置数据格式_哔哩哔哩_bilibili 快速输入数据与编辑数据 一个工作簿可以包含多个工作表 特殊数据的添加格式 输入负数, 例如-3、-5 常规输入, 直接输入-3、-5;使用(), 例如在单元格中输入(3)回车即可变为-3;上述括号不区分中…...
嵌入式EasyRTC实时通话支持海思hi3516cv610,编译器arm-v01c02-linux-musleabi-gcc
EasyRTC已经完美支持海思hi3516cv610,编译器arm-v01c02-linux-musleabi-gcc,总体SDK大小控制在680K以内(预计还能压缩100K上下): EasyRTC在hi3516cv610芯片上能双向通话、发送文字以及二进制指令,总体运行…...
在freertos中,中断优先级和任务优先级之间的关系和使用方法
中断优先级和任务优先级如何匹配?任务优先级不同任务之间该用多高的优先级?中断优先级不同中断中该用多高的优先级?中断优先级和任务优先级设置时,怎样设置可以让任务在调度时屏蔽中断?怎样设置可以让任务在调度时&…...
设置ollama接口能外部访问
为了配置Ollama以允许外网访问,你可以按照以下步骤进行操作: 确认Ollama服务已正确安装并运行: 使用以下命令检查Ollama服务的状态: bash Copy Code systemctl status ollama如果服务未运行,使用以下命令启动它&…...
Go GUI 框架, energy many-browser 示例解读
CEF 在 Go 中的应用实现 示例链接 1. 初始化和配置 在使用 CEF 创建基于浏览器的应用时,首先需要初始化并配置应用实例。 1.1 创建应用实例 // 创建CEF应用实例 app : cef.NewApplication()1.2 配置应用参数 // 设置缓存路径 rootCache : filepath.Join(const…...
Docker 部署 MongoDB | 国内阿里镜像
一、简易单机版 1、镜像拉取 docker pull registry.cn-hangzhou.aliyuncs.com/farerboy/mongo:8.0.5-rc1 2、运行镜像 docker run -it --name mongodb \ -e MONGO_INITDB_ROOT_USERNAMEmongoroot \ -e MONGO_INITDB_ROOT_PASSWORDmongoroot \ -v /wwwroot/opt/docker/mong…...
软件工程-软件设计
包括 从管理的观点看包括: 详细设计 概要设计 从技术的观点看包括: 数据设计(详细设计) 系统结构设计(概要设计) 过程设计(详细设计) 任务 分析模型——》设计模型——》设…...
Elasticsearch:15 年来致力于索引一切,找到重要内容
作者:来自 Elastic Shay Banon 及 Philipp Krenn Elasticsearch 刚刚 15 岁了!回顾过去 15 年的索引和搜索,并展望未来 15 年的相关内容。 Elasticsearch 刚刚成立 15 周年。一切始于 2010 年 2 月的一篇公告博客文章(带有标志性的…...
DeepSeek大模型一键部署解决方案:全平台多机分布式推理与国产硬件优化异构计算私有部署
DeepSeek R1 走红后,私有部署需求也随之增长,各种私有部署教程层出不穷。大部分教程只是简单地使用 Ollama、LM Studio 单机运行量化蒸馏模型,无法满足复杂场景需求。一些操作配置也过于繁琐,有的需要手动下载并合并分片模型文件&…...
Docker 部署 MySQL-5.7 单机版
一、镜像获取 # docker hub 镜像 docker pull farerboy/mysql:5.7 # 国内阿里镜像 docker pull registry.cn-hangzhou.aliyuncs.com/farerboy/mysql:5.7 以上两个镜像二选一即可 二、运行容器 docker run -dti --name mysql \n --privileged \n --cgroupns private \n --e…...
打破AI黑盒,拥抱开源力量:基于openGauss+DeepSeek的本地知识库,打造你的专属AI助手!
引言:什么是RAG和LLM? LLM (Large Language Model,大语言模型): 就像 ChatGPT 这样的 AI 模型,拥有强大的语言理解和生成能力,但它们的知识局限于训练数据,且可能产生“幻觉”(即生成不准确的信…...
java配置api,vue网页调用api从oracle数据库读取数据
一、主入口文件 1:java后端端口号 2:数据库类型 和 数据库所在服务器ip地址 3:服务器用户名和密码 二、映射数据库表中的数据 resources/mapper/.xml文件 1:column后变量名是数据库中存储的变量名 property的值是column值的…...
visual studio导入cmake项目后打开无法删除和回车
通过Cmakelists.txt导入的项目做删除和回车无法响应,需要点击项目,然后选择配置项目就可以了...
linux运行kettle 遇到问题汇总
1、把本地的repositories.xml 放在跟目录 2、配置机台名解析 vi /etc/hosts bogon是服务器名字,根据实际情况修改 3、指定内存和字符集 vi spoon.sh -Xms1024m -Xmx2048m -Dfile.encodingUTF-8 4、执行kettle job ./kitchen.sh /rep pg_kettle /user admin /pa…...
初识camel智能体(一)
同目录下配置环境变量.env,内容如下, apikey从魔搭社区获取 QWEN_API_KEY4ff3ac8f-aebc******** 先上干货代码,主代码如下: from colorama import Forefrom camel.societies import RolePlaying from camel.utils import prin…...
如何在Excel和WPS中进行翻译
文档翻译我们可以用在线翻译工具,Excel工作表的翻译使用在线翻译工具就不是特别方便,那么如何快速进行翻译呢,我们今天介绍在不同的场景下如何利用翻译函数和Python程序来实现单元格的快速翻译。 一、在wps中进行翻译 WPS是我们常用的办公软…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
