在 gRPC 中,可以使用 TLS/SSL 或 Token 认证来进行身份验证。以下是如何实现这两种认证方式的示例:
- TLS/SSL 认证:
使用 TLS/SSL 认证时,客户端和服务器都需要使用 SSL 证书进行身份验证和加密通信。
服务器端:
package main
import (
"crypto/tls"
"log"
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"your_package/your_proto"
)
func main() {
// Load server certificate and key
creds, err := credentials.NewServerTLSFromFile("server.crt", "server.key")
if err != nil {
log.Fatalf("Failed to load server credentials: %v", err)
}
// Create a gRPC server with TLS credentials
server := grpc.NewServer(grpc.Creds(creds))
your_proto.RegisterYourServiceServer(server, &YourService{})
// Start listening on a port
listener, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
if err := server.Serve(listener); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
客户端:
package main
import (
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"your_package/your_proto"
)
func main() {
// Load client certificate and key
creds, err := credentials.NewClientTLSFromFile("server.crt", "")
if err != nil {
log.Fatalf("Failed to load client credentials: %v", err)
}
// Dial the gRPC server with TLS credentials
conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
// Use the conn to create a client and make RPC calls
client := your_proto.NewYourServiceClient(conn)
// ...
}
- Token 认证:
在 gRPC 中,WithPerRPCCredentials
接口用于为每个 RPC 调用设置自定义的认证凭据。这使得在每个单独的 RPC 调用中都可以使用不同的认证信息。这种方法适用于需要每个 RPC 调用使用不同凭据的情况,比如使用短期令牌或动态生成的凭据。
WithPerRPCCredentials
的签名如下:
func WithPerRPCCredentials(creds PerRPCCredentials) DialOption
这里的 PerRPCCredentials
是一个接口,你需要实现这个接口来定义你自己的认证逻辑。接口定义如下:
type PerRPCCredentials interface {
GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
RequireTransportSecurity() bool
}
GetRequestMetadata
方法用于返回用于当前 RPC 调用的认证元数据,通常是一个键值对的映射。这些元数据将被添加到 gRPC 请求的标头中,用于认证。你可以在这里添加自己的认证信息。RequireTransportSecurity
方法指示是否需要传输层安全,通常返回true
。
以下是一个简单的示例,展示如何使用 WithPerRPCCredentials
接口为每个 RPC 调用设置自定义的 Token 认证凭据:
package main
import (
"context"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
type TokenCredential struct {
Token string
}
func (t TokenCredential) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + t.Token,
}, nil
}
func (t TokenCredential) RequireTransportSecurity() bool {
return true
}
func main() {
creds := TokenCredential{
Token: "your_access_token",
}
opts := []grpc.DialOption{
grpc.WithTransportCredentials(credentials.NewTLS(nil)),
grpc.WithPerRPCCredentials(creds),
}
conn, err := grpc.Dial("localhost:50051", opts...)
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
// Use the connection for RPC calls
// ...
}
在上面的示例中,TokenCredential
结构实现了 PerRPCCredentials
接口,用于设置每个 RPC 调用的认证元数据。通过使用 WithPerRPCCredentials
接口,我们将自定义的 Token 认证凭据应用于 gRPC 连接,并为每个 RPC 调用添加了认证标头。
以上示例演示了如何在 gRPC 中实现 TLS/SSL 和 Token 认证。选择适合你项目需求的认证方式,并根据实际情况进行配置。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意