1. 前言

前情回顾

go语言gRPC系列(一) - gRPC入门

之前我们演示的客户端和服务端之间是没有使用证书的,不是很安全。下面演示一下,服务调用之间加入自签的证书验证。

生产环境以网上购买的证书为准

2. 生成自签证书

2.1 MAC生成自签证书的教程链接:

https://www.jianshu.com/p/4cdd29ce424d

2.2 Windows生成自签证书的教程

  1. 登录如下链接

http://slproweb.com/products/Win32OpenSSL.html

  1. 下载如下的openssl工具

  1. 安装到某个目录
  2. 进入安装目录的bin文件夹下
  3. 在所在的文件夹打开cmd,并输入openssl

  1. 然后再执行如下的操作, 生成私钥文件
  • 会生成一个server.key
genrsa -des3 -out server.key 2048

  1. 创建证书请求
  • 会生成一个server.csr
genrsa -des3 -out server.key 2048

  1. 为了演示简单,删除私钥中的密码
  • 会生成一个server_no_password.key
rsa -in server.key -out server_no_password.key

  1. 生成公钥文件
  • 会生成server.crt
x509 -req -days 365 -in server.csr -signkey server_no_password.key -out server.crt


3. 改造服务端使用自签证书

3.1 复制证书至代码下

在服务端的目录下新建一个keys文件夹,并且上之前生成的server_no_password.keyserver.crt复制到目录下

3.2 改造代码添加证书认证

改造之前上一节的服务端代码,具体改造的部分如下标红的部分

完整的服务端代码:

package main

import (
"gomicro-quickstart/grpc_server/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"log"
"net"
) func main() {
// 1. 引用证书
tls, err := credentials.NewServerTLSFromFile("grpc_server/keys/server.crt", "grpc_server/keys/server_no_password.key")
if err != nil {
log.Fatal("服务端获取证书失败: ", err)
} // 2. new一个grpc的server,并且加入证书
rpcServer := grpc.NewServer(grpc.Creds(tls)) // 3. 将刚刚我们新建的ProdService注册进去
service.RegisterProdServiceServer(rpcServer, new(service.ProdService)) // 4. 新建一个listener,以tcp方式监听8082端口
listener, err := net.Listen("tcp", ":8082")
if err != nil {
log.Fatal("服务监听端口失败", err)
} // 5. 运行rpcServer,传入listener
_ = rpcServer.Serve(listener)
}

3.1 运行代码并查看客户端的访问错误

运行server服务端

这时候我们同样运行起来client,发现会报如下的错,因为我们的服务端使用证书加密了

4. 改造客户端代码(单向认证)

4.1 复制公钥给客户端

这里为了刚入门演示方便,采用了单向认证。

  1. 在客户端代码下新建keys文件夹
  2. 将server.crt复制到keys文件夹下

4.2 改造客户端代码

较上一章的代码的改动如下图:

完整的客户端代码如下:

package main

import (
"context"
"fmt"
"gomicro-quickstart/grpc_client/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"log"
) func main() {
// 1. 添加公钥证书的引用, codepie.fun是之前生成证书的时候填写的common name
tls, err := credentials.NewClientTLSFromFile("grpc_client/keys/server.crt", "codepie.fun") if err != nil {
log.Fatal("客户端获取证书失败: ", err)
} // 2. 新建连接,端口是服务端开放的8082端口
conn, err := grpc.Dial(":8082", grpc.WithTransportCredentials(tls))
if err != nil {
log.Fatal(err)
} // 退出时关闭链接
defer conn.Close() // 3. 调用Product.pb.go中的NewProdServiceClient方法
productServiceClient := service.NewProdServiceClient(conn) // 4. 直接像调用本地方法一样调用GetProductStock方法
resp, err := productServiceClient.GetProductStock(context.Background(), &service.ProductRequest{ProdId: 233})
if err != nil {
log.Fatal("调用gRPC方法错误: ", err)
} fmt.Println("调用gRPC方法成功,ProdStock = ", resp.ProdStock)
}

4.3 运行客户端查看结果

单向认证成功,服务调用成功

go语言gRPC系列(二) - 为gRPC添加证书的更多相关文章

  1. cacti系列(二)之cacti添加对tomcat服务器的监控

    cacti添加对tomcat的监控 1.首先下载监控tomcat的模板 TomcatStats-0.1.zip    2.导入模板 (cacti_host_template_tomcat_server ...

  2. 【数据结构(C语言版)系列二】 栈

    栈和队列是两种重要的线性结构.从数据结构角度看,栈和队列也是线性表,但它们是操作受限的线性表,因此,可称为限定性的数据结构.但从数据类型角度看,它们是和线性表大不相同的两类重要的抽象数据类型. 栈的定 ...

  3. Go语言入门系列(四)之map的使用

    本系列前面的文章: Go语言入门系列(一)之Go的安装和使用 Go语言入门系列(二)之基础语法总结 Go语言入门系列(三)之数组和切片 1. 声明 map是一种映射,可以将键(key)映射到值(val ...

  4. Go语言入门系列(五)之指针和结构体的使用

    Go语言入门系列前面的文章: Go语言入门系列(二)之基础语法总结 Go语言入门系列(三)之数组和切片 Go语言入门系列(四)之map的使用 1. 指针 如果你使用过C或C++,那你肯定对指针这个概念 ...

  5. Go语言入门系列(六)之再探函数

    Go语言入门系列前面的文章: Go语言入门系列(三)之数组和切片 Go语言入门系列(四)之map的使用 Go语言入门系列(五)之指针和结构体的使用 在Go语言入门系列(二)之基础语法总结这篇文章中已经 ...

  6. 微服务系列(二)GRPC的介绍与安装

    微服务系列(二)GRPC的介绍与安装 1.GPRC简介 GRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架.GRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多 ...

  7. go语言gRPC系列(三) - 使用grpc-gateway同时提供HTTP和gRPC服务

    1. gRPC提供HTTP服务 1.1 存在的意义 1.2 代码示例 1.3 使用postman尝试调用 1.4 gRPC客户端代码调用 2. 使用grpc-gateway同时提供HTTP和gRPC服 ...

  8. 初识google多语言通信框架gRPC系列(一)概述

    gRPC概述 3/26/2016 9:16:08 AM 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 一直在寻找多平台多语言的通信框架,微软的WCF框架很强大和灵 ...

  9. 初识google多语言通信框架gRPC系列(四)C++中使用gRPC

    我的这几篇文章都是使用gRPC的example,不是直接编译example,而是新建一个项目,从添加依赖,编译example代码,执行example.这样做可以为我们创建自己的项目提供借鉴.如果对gR ...

随机推荐

  1. Zabbix4.x如何安全传输数据

    由于设备都在混合云,所以不少数据传输是通过公网,这样极大的增加了危险性,所以在Zabbix数据传输这块则进行PSK安全认证,由proxy主动收集agent数据后统一发送给server,这样只需要对pr ...

  2. 架构师都该懂的 CAP 定理

    面对可能出现的网络延迟,不可预估的请求流量等情况,设计一个分布式系统,我们通常围绕系统高可用,数据一致性的目标去规划和实现,想要完全实现这个目标,却并非易事.由此,分布式系统领域诞生了一个基本定理,即 ...

  3. STL源码剖析:迭代器

    准备知识 什么是迭代器? 迭代器是链接容器和算法的桥梁,所有的算法都通过迭代器操作容器中的数据 迭代器是一种智能指针,最重要的操作符重载就是operator*,operator-> 迭代器的实现 ...

  4. 设计模式:prototype模式

    使用场景:在不能根据类创建对象的时候,根据已有的对象创建对象 不能根据类创建对象的情况: 创建一个类的对象时,需要根据多种对象来创建,创建的过程非常复杂 难以根据类生成对象 例子: class Pro ...

  5. Git报错问题集锦

    git merge合并时遇上refusing to merge unrelated histories的解决方案 如果git merge合并的时候出现refusing to merge unrelat ...

  6. 看了这篇你就会手写RPC框架了

    一.学习本文你能学到什么? RPC的概念及运作流程 RPC协议及RPC框架的概念 Netty的基本使用 Java序列化及反序列化技术 Zookeeper的基本使用(注册中心) 自定义注解实现特殊业务逻 ...

  7. ls -bash: ls: command not found

    ls -bash: ls: command not found原因:在设置环境变量时,编辑profile文件没有写正确,导致在命令行下 ls等命令不能够识别.解决方案: export PATH=/us ...

  8. jenkins初学部分笔记网站

    https://www.cnblogs.com/wfd360/p/11314697.html 自动化部署详细教程 https://blog.csdn.net/weixin_41948075/artic ...

  9. PHP date_interval_format() 函数

    ------------恢复内容开始------------ 计算两个日期间的间隔,然后格式化时间间隔: 实例 <?php $date1=date_create("2013-01-01 ...

  10. PHP atan() 函数

    实例 通过 atan() 函数返回不同数的反正切: <?phpecho(atan(0.50) . "<br>");echo(atan(-0.50) . " ...