grpc之golang使用拦截器验证身份
前面的虽然实现了接口请求验证,但是需要在每个方法都加一个验证,有点不太友好,所以调整一下使用服务端拦截器。
- 修改register.go文件 调整前
func Register() *grpc.Server {
s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
greeter.RegisterGreeterServer(s, &Greeter{})
carrier.RegisterCarrierServer(s, &Carrier{})
token.RegisterTokenServer(s, &Token{})
file.RegisterFileServer(s, &File{})
return s
}
调整后
func Register() *grpc.Server {
//s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
s := grpc.NewServer(grpc.UnaryInterceptor(unaryInterceptor))
greeter.RegisterGreeterServer(s, &Greeter{})
carrier.RegisterCarrierServer(s, &Carrier{})
token.RegisterTokenServer(s, &Token{})
file.RegisterFileServer(s, &File{})
return s
}
增加拦截器方法
// 一般拦截器
func unaryInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
// authentication (token verification)
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Errorf(codes.Unauthenticated, "获取token失败")
}
var str string
if value, ok := md["accesstoken"]; ok {
str = value[0]
}
tokenStr := tool.TokenDeCode(str)
if !ok {
return nil, errMissingMetadata
}
var user token.UserRequest
json.Unmarshal([]byte(tokenStr), &user)
if user.UserName != "wms" || user.PassWord != "123456" {
return nil, status.Errorf(codes.Unauthenticated, "Token无效")
}
m, err := handler(ctx, req)
if err != nil {
return nil, err
}
return m, err
}
// 流式拦截器
type wrappedStream struct {
grpc.ServerStream
}
func (w *wrappedStream) RecvMsg(m any) error {
return w.ServerStream.RecvMsg(m)
}
func (w *wrappedStream) SendMsg(m any) error {
return w.ServerStream.SendMsg(m)
}
func newWrappedStream(s grpc.ServerStream) grpc.ServerStream {
return &wrappedStream{s}
}
func streamInterceptor(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
// authentication (token verification)
md, ok := metadata.FromIncomingContext(ss.Context())
if !ok {
return errMissingMetadata
}
if !ok {
return status.Errorf(codes.Unauthenticated, "获取token失败")
}
var str string
if value, ok := md["accesstoken"]; ok {
str = value[0]
}
tokenStr := tool.TokenDeCode(str)
if !ok {
return errMissingMetadata
}
var user token.UserRequest
json.Unmarshal([]byte(tokenStr), &user)
if user.UserName != "wms" || user.PassWord != "123456" {
return status.Errorf(codes.Unauthenticated, "Token无效")
}
err := handler(srv, newWrappedStream(ss))
return err
}