grpc 拦截器 python_grpc 拦截器【 go 和 asp.net core的实现】

GO

大类可分为两种 RPC 方法,与拦截器的对应关系是:普通方法:一元拦截器(grpc.UnaryInterceptor);流方法:流拦截器(grpc.StreamInterceptor)。

1.拦截器的实现   我们来看看他的实现。在\gogrpcjwt\api\authtoken.go文件我们增加方法 AuthInterceptor【我们的值 是通过context来存储的】

/*ctx context.Context:请求上下文

req interface{}:RPC 方法的请求参数

info *UnaryServerInfo:RPC 方法的所有信息

handler UnaryHandler:RPC 方法本身*/func AuthInterceptor(ctx context.Context, reqinterface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {

userName :=CheckAuth(ctx)

log.Printf("gRPC method: %s, %v", info.FullMethod, req)

newCtx :=ctxif len(userName) > 0{//使用context.WithValue添加了值后,可以用Value(key)方法获取值

newCtx = context.WithValue(ctx, "username", userName)//log.Println(newCtx.Value("username"))

}returnhandler(newCtx, req)

}

2.注册拦截器 servertls\main.go

//rpcServer := grpc.NewServer()

opts :=[]grpc.ServerOption{

grpc_middleware.WithUnaryServerChain(

api.AuthInterceptor,

)}

rpcServer := grpc.NewServer(opts...)

3.获取用户信息 修改api/handler.go的SayHello 方法:

//userName := CheckAuth(ctx)

userName := fmt.Sprintf("%v", ctx.Value("username"))

4运行结果正常

D:\GoProject\src\gogrpcjwt\clienttls>go run main.go2021/01/06 16:45:24 Response fromserver: bar gavin

http call.....2021/01/06 16:45:24 {"greeting":"bar gavin"}

asp.net core 5.0

在C# 里面分客户端【个人觉得 意义不大,比如我用html 只能访问httpapi】 和服务端

1.创建拦截器AuthInterceptor.cs ,继承拦截器基类 Interceptor

usingGrpc.Core;usingGrpc.Core.Interceptors;usingMicrosoft.IdentityModel.Tokens;usingSystem;usingSystem.Collections.Generic;usingSystem.IdentityModel.Tokens.Jwt;usingSystem.Linq;usingSystem.Security.Claims;usingSystem.Text;usingSystem.Threading.Tasks;namespacegrpcserver

{public classAuthInterceptor:Interceptor

{const string tokenSchema = "Bearer";const string tokenIssuer = "https://localhost:5001";const string tokenAudience = "grpc";const string tokenSecurityKey = "asp.netcore5.0grpcjwt";public override Task UnaryServerHandler(

TRequest request,

ServerCallContext context,

UnaryServerMethodcontinuation)

{var userContext =context.GetHttpContext().User;string userName =userContext.FindFirstValue(ClaimTypes.Name);if (string.IsNullOrEmpty(userName)) {string tokenStr = context.GetHttpContext().Request?.Headers["Authorization"];if (!string.IsNullOrEmpty(tokenStr))

{if(tokenStr.StartsWith(tokenSchema))

{

tokenStr= tokenStr.Split(' ')[1];

}

SecurityToken token;var key = newSymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenSecurityKey));

ClaimsPrincipal claims= new JwtSecurityTokenHandler().ValidateToken(tokenStr, newTokenValidationParameters

{

ValidAudience=tokenAudience,

ValidIssuer=tokenIssuer,

IssuerSigningKey=key

},outtoken);

context.GetHttpContext().User=claims;

}

}returncontinuation(request, context);

}

}

}

2.注册拦截器 Startup.cs的ConfigureServices 方法

services.AddGrpc(x=>x.Interceptors.Add());

3.修改调用程序GreeterService.cs的SayHello

//var userName= CheckAuth(context)??string.Empty;

var userName = context.GetHttpContext().User.FindFirstValue(ClaimTypes.Name);

4.运行结果:

备注,像这种获取信息的, 我个人还是推荐 直接用方法 调用来的实惠,拦截器 类似管道 我一般 用于处理系统级的问题, 开发感觉不到, 比如 统一日志

下载地址: https://github.com/dz45693/asp.netgrpccert.git 【C#】https://github.com/dz45693/gogrpcjwt.git【Go】

参考

https://www.cnblogs.com/stulzq/p/11840535.html

你可能感兴趣的:(grpc,拦截器,python)