Golang Grpc接口调用实现账号密码认证

GRPC实现案例

1.客户端认证凭证实现
Go 复制代码
package auth

import "context"

type Authentication struct {
	clientId     string
	clientSecret string
}

// 构造凭证
func NewClientAuthentication(clientId, clientSecret string) *Authentication {
	return &Authentication{
		clientId:     clientId,
		clientSecret: clientSecret,
	}
}

// 初始化凭证
func (a *Authentication) InitClientCredentials(clientId, clientSecret string) {
	a.clientId = clientId
	a.clientSecret = clientSecret
}

// 获取凭证
func (a *Authentication) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
	return map[string]string{
		"clientId":     a.clientId,
		"clientSecret": a.clientSecret,
	}, nil
}

// 凭证是否需要安全传输
func (a *Authentication) RequireTransportSecurity() bool {
	return false
}

客户端连接设置

Go 复制代码
conn, err := grpc.NewClient(addr,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithPerRPCCredentials(auth.NewClientAuthentication("admin", "123456")))
2.服务端认证实现
Go 复制代码
package auth

import (
	"context"
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

const (
	ClientHeaderKey = "clientId"
	ClientSecretKey = "clientSecret"
)

type GrpcAuthor struct {

}

// 构造并初始化
func NewGrpcAuthor() *GrpcAuthor {
	return &GrpcAuthor{}
}

// 从客户端发来的请求中获取凭证信息
func (a *GrpcAuthor) GetClientCredentialsFromMeta(md metadata.MD) (
	clientId, clientSecret string) {
	cids := md.Get(ClientHeaderKey)
	sids := md.Get(ClientSecretKey)
	if len(cids) > 0 {
		clientId = cids[0]
	}
	if len(sids) > 0 {
		clientSecret = sids[0]
	}
	return
}

// 验证凭证信息
func (a *GrpcAuthor) validateServiceCredential(clientId, clientSecret string) error {
	if clientId == "" && clientSecret == "" {
		return status.Errorf(codes.Unauthenticated, "client_id or client_secret is \"\"")
	}
	if !(clientId == "admin" && clientSecret == "123456") {
		return status.Errorf(codes.Unauthenticated, "client_id or client_secret invalidate")
	}
	return nil
}

// 拦截器
func (a *GrpcAuthor) Auth(
	ctx context.Context,
	req interface{},
	info *grpc.UnaryServerInfo,
	handler grpc.UnaryHandler,
) (resp interface{}, err error) {
	// 从上下文中获取认证信息
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return nil, fmt.Errorf("ctx is not an grpc incoming context!")
	}

	fmt.Println("grpc header info :", md)

	// 获取客户端凭证信息
	clientId, clientSecret := a.GetClientCredentialsFromMeta(md)

	// 校验调用的客户端携带的凭证是否有效
	if err := a.validateServiceCredential(clientId, clientSecret); err != nil {
		return nil, err
	}

	resp, err = handler(ctx, req)
	return resp, err
}

func GrpcAuthUnaryServerInterceptor() grpc.UnaryServerInterceptor {
	return NewGrpcAuthor().Auth
}

服务端提供设置

Go 复制代码
s := grpc.NewServer(
		grpc.UnaryInterceptor(auth.GrpcAuthUnaryServerInterceptor()), // 添加认证插件
	)

若账号密码错误返回:

具体的案例实现,修改其中部分即可验证。

相关推荐
wuyk55536 分钟前
12.归并排序:分治思想的稳定排序算法
开发语言·数据结构·算法·排序算法
吴声子夜歌40 分钟前
ApacheCommons——commons-text(模板替换与文本算法)
java·开发语言·算法·apache
玉宇夕落1 小时前
背单词项目一:融会贯通:从零构建"单词大师"后台——Next.js + Supabase + Drizzle 全栈开发实战
后端
quantdash_cc1 小时前
量化数据源怎么选:稳定性、实时性和数据完整性到底该如何权衡?
开发语言·python·数据分析·量化交易·股票数据·quantdash
橙序员小站1 小时前
从 Demo 到生产:Agent Harness 如何把 AI 真正“接”进项目
后端·aigc·ai编程
萧瑟余晖2 小时前
Java深入解析篇五十四之对象模型详解
java·开发语言
她的男孩2 小时前
一个开源低代码框架的协作 SPI 是怎么设计的 ForgeAdmin 拆解 + 实战接入新平台
后端·算法·架构
蓝山6162 小时前
Python 字典(Dictionary)完全指南:从入门到实战
后端
foggyprojects2 小时前
在 DeepSeek Harness 里跑通 Foggy:从安装插件到第一次问数
后端
张文是假的啊2 小时前
Java | record | Controller逻辑
java·开发语言