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. 使用SQL语句进行特定值排序

    使用SQL语句进行查询时,对数据进行排序,排序要求为排序的一个字段中特定值为顶部呈现: select * from TableName order by case TableFieldName whe ...

  2. java并发编程[持续更新]

    目录 java并发编程 1.常用类介绍 Semaphore 2.名词解释 2.1 线程安全 2.2 可重入锁和不可重入锁 java并发编程 1.常用类介绍 Semaphore Semaphore 类是 ...

  3. mybatis连接池

    连接池 在 Mybatis 中,数据源 dataSource 共有三类,分别是: UNPOOLED : 不使用连接池的数据源.采用传统的 javax.sql.DataSource 规范中的连接池,My ...

  4. 数据库事务与MySQL事务总结

    事务特点:ACID 从业务角度出发,对数据库的一组操作要求保持4个特征: Atomicity(原子性):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败 ...

  5. 从零开始学Python网络爬虫PDF高清完整版免费下载|百度网盘

    百度网盘:从零开始学Python网络爬虫PDF高清完整版免费下载 提取码:wy36 目录 前言第1章 Python零基础语法入门 11.1 Python与PyCharm安装 11.1.1 Python ...

  6. 4.pandas的进阶查询

    简单的查询其实根本不能满足实际开发的需求 需求可能是让你查一下2018年的销售额啊,2019年温度超过30℃的天数啊等等的 这些需求都是有异曲同工的,就是带条件的查询 这里我们先自己设计一个表格,并将 ...

  7. PHP curl_share_close函数

    (PHP 5 >= 5.5.0) curl_share_close — 关闭 cURL 共享句柄 说明 void curl_share_close ( resource $sh ) 关闭 cUR ...

  8. Netty(一):server启动流程解析

    netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...

  9. Jvm相关文章

    深入理解JVM-内存模型(jmm)和GC https://www.jianshu.com/p/76959115d486

  10. Redis 内存压缩原理

    Redis 无疑是一个大量消耗内存的数据库,因此 Redis 引入了一些设计巧妙的数据结构进行内存压缩来减轻负担.ziplist.quicklist 以及 intset 是其中最常用最重要的压缩存储结 ...