Node.js gRPC如何使用用户名密码凭据访问无证书gNMI接口
访问无证书配置的Arista gNMI API(用户名/密码认证)的gRPC-js配置方案
问题场景
- 目标:访问Arista路由器的gNMI API,接口仅启用
admin/admin用户名密码认证,未配置合法TLS证书 - 已验证可用的gnmic CLI命令:
gnmic -a 10.72.47.100:32232 --username admin --password admin --skip-verify capabilities
- 技术栈:
@grpc/grpc-js+ts-proto生成的TypeScript数据模型,调用时先后触发两类错误:- 组合不安全通道凭据+调用凭据时,报错
Error: Cannot compose insecure credentials - 直接传入携带用户名密码的Metadata调用时,报错
Error: 14 UNAVAILABLE: Connection dropped
- 组合不安全通道凭据+调用凭据时,报错
报错根因
- 第一个报错是
@grpc/grpc-js的固有机制:不允许为明文不安全通道组合附加调用凭据,因此combineChannelCredentials传入createInsecure()生成的通道凭据时会直接抛错。 - 第二个报错有两个诱因:
- 核心原因:Arista设备的gNMI服务默认监听TLS端口,哪怕没有配置合法证书,也不会接收明文gRPC请求。使用
createInsecure()发起明文连接,相当于用HTTP请求连HTTPS端口,服务端会直接断开连接。注意gnmic命令里的--skip-verify是跳过TLS证书校验,不是走明文连接。 - 代码语法错误:第二段示例里变量名大小写不匹配(定义的是大写开头的
Credentials,传入client时用了小写credentials),且调用capabilities方法时,Metadata参数和回调函数之间缺少逗号分隔。
- 核心原因:Arista设备的gNMI服务默认监听TLS端口,哪怕没有配置合法证书,也不会接收明文gRPC请求。使用
正确实现代码
import * as grpc from '@grpc/grpc-js'; import * as gnmi from './proto/github.com/openconfig/gnmi/proto/gnmi/gnmi'; // 1. 创建跳过证书校验的TLS通道凭据,等价于gnmic的--skip-verify参数 const channelCredentials = grpc.credentials.createSsl( null, null, null, { // 关闭证书合法性校验,适配设备自签/无证书场景 rejectUnauthorized: false } ); // 2. 组装认证用Metadata const meta = new grpc.Metadata(); meta.add('username', 'admin'); meta.add('password', 'admin'); // 3. 初始化客户端 const client = new gnmi.gNMIClient('10.72.47.100:32232', channelCredentials); const req: gnmi.CapabilityRequest = { extension: [] }; // 4. 调用时传入Metadata,注意参数之间用逗号分隔 client.capabilities(req, meta, (error, response) => { if (error) { console.error(error); process.exit(1); } console.info(response.gNMIVersion); });
补充说明
如果不想每次调用都手动传Metadata,可以写客户端拦截器自动给所有请求追加认证头,不需要组合通道凭据和调用凭据。
内容的提问来源于stack exchange,提问作者Jesper Kristiansen
相关产品推荐
相关产品推荐

