【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是我们常用的办公软…...
CES 2016行业转向:从酷炫到实用,安全与服务成核心
1. 从“酷炫”到“实用”:CES 2016的行业转向解析每年一月的拉斯维加斯,对于科技行业而言,都像是一场盛大的朝圣。CES(国际消费电子展)不仅是新品发布的舞台,更是行业风向的晴雨表。2016年的CES,…...
C++异步日志系统
文章目录异步日志系统1. 项目背景2. 设计思路2.1 核心架构2.2 关键技术点3. 实现细节3.1 线程安全的日志队列 (LogQueue)3.2 动态格式化与回退机制 (formatMessage)3.3 自动化管理4. 接口说明日志级别 (LogLevel)核心方法5. 使用指南5.1 快速上手5.2 注意事项6. 总结7.Code异步…...
保险科技前端开源方案Insura:动态表单与保费试算核心实现
1. 项目概述:一个面向保险行业的开源前端解决方案最近在梳理一些开源项目时,发现了一个挺有意思的仓库:Rashed-ux920/insura。从名字上拆解,“insura”显然是“Insurance”(保险)的缩写,而作者“…...
为什么电路中的阻抗需要引入复数?
1、方便计算说法▼无他,就是图个方便计算而已。请看下题,求如图所示电路中电流的大小。电流的频率与电压频率相同,无非就是求解幅值的变化和相位的变化。▼引用一下以前我的一个知乎回答,数学中的数先是从一维数轴开始。▼因电路的…...
【信息科学与工程学】【物理/化学科学和工程技术】知识体系018 第十八篇 界面科学02 界面化学特征 (1)
表3 界面化学特征 完整知识地图框架 第一部分:3.1 界面结构与缺陷 3.1.1 界面原子构型 (50个) 3.1.1.1 共格界面 3.1.1.2 半共格界面 3.1.1.3 非共格界面 3.1.1.4 重构界面 3.1.1.5 驰豫界面 3.1.1.6 晶格失配 3.1.1.7 临界厚度 3.1.1.8 失配位错 3.1.1.9 失配位错…...
卫星热真空测试中射频功率测量的关键技术突破
1. 卫星热真空测试中的射频功率测量挑战在卫星研制过程中,热真空测试(TVAC)是验证航天器能否承受太空极端环境的关键环节。测试环境需要模拟太空中的高真空(<510⁻⁶ Torr)和极端温度(-196℃至140℃&…...
Flutter中如何显示异步数据
在开发Flutter应用时,处理异步操作是非常常见的任务之一。许多时候,我们需要将异步操作的结果展示在用户界面上,比如从服务器获取数据或执行一些耗时的计算。本文将通过一个具体的实例,展示如何在Flutter中使用FutureBuilder来处理和显示异步数据。 问题背景 假设我们有一…...
Conforme配置管理范式:类型安全与约定优先的实践指南
1. 项目概述:Conforme,一个被低估的配置管理范式在软件开发和系统运维的日常里,我们总在和“配置”打交道。数据库连接字符串、API密钥、功能开关、环境变量……这些看似零散的信息,却像乐谱上的音符,共同决定了应用如…...
为什么向量空间必须是“无限”的?
为什么向量空间必须是“无限”的? 为什么说运算结果总是在 V 中? 向量空间的定义本质上就是划定了一个“无论你怎么加、怎么乘,都逃不出这个圈子”的集合。那么为什么还分V,U 子集呢,这样讲来,不就是一个向量空间包括一切的意思吗? 当数学家说“地板是一个向量空间(子…...
TCP 零窗口(Zero Window)是什么?一篇讲清楚成因、抓包特征、和拥塞/丢包的区别
TCP 零窗口(Zero Window)是什么?一篇讲清楚成因、抓包特征、和拥塞/丢包的区别 在很多网络故障现场里,业务方会一句话描述问题:“链路没断、带宽也不满,但接口就是慢,上传像堵住了一样。” 这类…...
