在许多现代的微服务架构中,gRPC(Google Remote Procedure Call)因其高效的通讯性能和跨语言服务的接口定义能力而受到欢迎。安全的访问控制在 gRPC 中至关重要,它确保了只有合法认证的用户或服务能够调用 gRPC 服务。本文将一步步介绍如何在 Python 中实现 gRPC 认证,在开始之前,我们先准备一款 gRPC 调试工具。

gRPC 调试工具
为了优化 gRPC 的调试体验,选择一个可靠的调试工具至关重要。这里我比较推荐使用 Apifox —— 一款支持多种协议(如 http、https、WebSocket、Socket、gRPC、Dubbo 等)的全能接口测试工具。下面,我们将通过具体步骤演示如何在 Python 中进行 gRPC 认证,并借助 Apifox 进行高效调试。

Python 中进行 gRPC 认证
步骤 1: 环境搭建
首先,确保你安装了 Python 环境以及grpcio
和grpcio-tools
两个库。你可以使用 pip 安装它们:
pip install grpcio grpcio-tools
步骤 2: 定义你的 gRPC 服务
假设你已经有了一个.proto
文件定义了 gRPC 服务和消息类型。举个例子, example.proto
:
syntax = "proto3";
package example;
// 定义了一个Greeter服务
service Greeter {
// 发出问候的远程方法
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 问候的请求消息
message HelloRequest {
string name = 1;
}
// 问候的回复消息
message HelloReply {
string message = 1;
}
步骤 3: 生成服务代码
使用下面的命令从.proto
文件生成 Python 代码:
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. example.proto
在当前目录中,你会看到生成的example_pb2.py
和example_pb2_grpc.py
文件。
步骤 4: 实现服务端
接下来在服务端实现认证机制。gRPC 支持多种认证方式,常见的有 SSL/TLS 认证和 Token 认证。
SSL/TLS 认证
import grpc
from example_pb2_grpc import GreeterServicer, add_GreeterServicer_to_server
from example_pb2 import HelloReply
# 创建gRPC服务器
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 实现Greeter服务接口
class Greeter(GreeterServicer):
def SayHello(self, request, context):
return HelloReply(message='Hello, %s!' % request.name)
# 添加服务到服务器中
add_GreeterServicer_to_server(Greeter(), server)
# 生成服务器端证书和私钥
with open('server.crt', 'rb') as f:
server_certificate = f.read()
with open('server.key', 'rb') as f:
private_key = f.read()
# 创建SSL上下文
server_credentials = grpc.ssl_server_credentials(((private_key, server_certificate),))
# 为服务器添加安全策略
server.add_secure_port('[::]:50051', server_credentials)
# 启动gRPC服务器
server.start()
server.wait_for_termination()
Token 认证
import grpc
from example_pb2_grpc import GreeterServicer, add_GreeterServicer_to_server
from example_pb2 import HelloReply
# 创建Token认证的拦截器
class TokenAuthInterceptor(grpc.ServerInterceptor):
def __init__(self, valid_token):
self.valid_token = valid_token
def intercept_service(self, continuation, handler_call_details):
# 从context中获取metadata
metadata = dict(handler_call_details.invocation_metadata)
# 检查token是否合法
if metadata.get('authorization') != self.valid_token:
return grpc.unary_unary_rpc_terminator(
grpc.StatusCode.UNAUTHENTICATED, 'Invalid token!')
return continuation(handler_call_details)
# 创建gRPC服务器,并添加拦截器
interceptor = TokenAuthInterceptor(valid_token='your_secret_token')
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=(interceptor,))
# ...
# 后续代码与上面的SSL/TLS认证中一样
步骤 5: 实现客户端
客户端需要传递正确的认证信息以调用服务端的方法。
SSL/TLS 认证
import grpc
from example_pb2_grpc import GreeterStub
from example_pb2 import HelloRequest
# 从文件读取客户端证书
with open('client.crt', 'rb') as f:
server_certificate = f.read()
# 创建SSL上下文
ssl_credentials = grpc.ssl_channel_credentials(root_certificates=server_certificate)
# 创建一个安全的gRPC通道
channel = grpc.secure_channel('localhost:50051', ssl_credentials)
# 创建服务存根
stub = GreeterStub(channel)
# 发起RPC调用
response = stub.SayHello(HelloRequest(name='World'))
print(response.message)
Token 认证
import grpc
from example_pb2_grpc import GreeterStub
from example_pb2 import HelloRequest
# 添加Token
def set_token(metadata):
return (('authorization', 'your_secret_token'),)
# 创建gRPC通道,添加Token
channel = grpc.intercept_channel(
grpc.insecure_channel('localhost:50051'),
grpc.metadata_call_credentials(set_token)
)
# 创建服务存根
stub = GreeterStub(channel)
# 发起RPC调用
response = stub.SayHello(HelloRequest(name='World'))
print(response.message)
步骤 6:运行
结合上述的服务端和客户端代码示例,在运行最终结果之前,确保你已经创建了合适的 SSL/TLS 证书和私钥,并将其放置在适当的路径下,如果你选择了 Token 认证,则保证 Token 的一致性。
执行步骤:
1.运行服务端代码。打开一个命令行窗口,确保你的工作目录是服务端代码所在的位置,并运行它:
python server.py
2.在一个新的命令行窗口中,运行客户端代码。同样地,确定你的工作目录是客户端代码所在的位置,并运行它:
python client.py
如果所有一切设置正确,你的客户端将会与服务端建立连接。客户端发送一个"HelloRequest",并包含它希望服务端回复的"Name"。服务端将接收到这个请求,检查认证信息,并返回一个"HelloReply",其中包含了对应的问候消息。
对于 SSL/TLS 认证,服务端的输出应该没有错误消息,表示服务成功启动。客户端运行后,应该在控制台输出类似于以下内容:
Hello, World!
对于 Token 认证,如果 Token 正确,你应该会见到一个类似的问候信息。如果 Token 不匹配,客户端会接收到一个认证错误,不会打印问候信息。
请注意,上述代码仅作为演示目的,实际在生产环境中使用时,应确保证书的安全存储和传输,以及 Token 的安全管理。此外,还要考虑证书的更新和撤销策略,以维护系统的安全性。
使用 Apifox 调试 gRPC
目前,市面上能够兼容 gRPC 接口的调试与管理工具相对有限,但值得注意的是,Apifox 作为业界领先的接口管理工具,已经支持 gRPC 接口的调试和管理功能,这一功能的推出使得在微服务架构中广泛应用的 gRPC 变得更加便捷。Apifox 提供全面的兼容性,涵盖 gRPC 的四种调用类型:
- Unary:一元调用
- Server Streaming:服务端流
- Client Streming:客户端流
- Bidirectional Streaming:双向流
下文将通过一个示例场景简要演示如何在 Apifox 中新建 gRPC 项目并针对接口发起调试。
步骤1:新建 gRPC 项目
在 Apifox 中登录并新建一个 gRPC 项目,点击“新建项目”按钮,选择 gRPC 类型,填写项目名称后轻点“新建”按钮。

步骤2:导入.proto
文件
导入定义 gRPC 接口所使用的服务、方法和消息的 .proto
文件。你可以将文件拖拽至其中或使用文件在线 URL 完成导入。

步骤3:调试 gRPC
文件导入后,Apifox 将基于 .proto
文件内容生成对应的接口信息,然后就可以进行调试。

通过这些简单的步骤,你可以在 Apifox 中方便地管理和调试你的 gRPC 项目。这个功能非常强大,更具体的你可以访问 Apifox 的 gRPC 帮助文档,赶快去试试吧!

总结
在这篇文章中,我们一步一步地学习了如何在 Python 中为 gRPC 服务实现 SSL/TLS 和 Token 认证。通过实际代码示例,我们展示了如何安全地建立服务端与客户端之间的通信,确保了数据交换的安全性。更多细节你可以去参考一下 gRPC 官方文档的描述。
知识拓展:
参考链接: