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. p40_数据交换方式

    一.为什么要数据交换 数据链路发展史: 二.数据交换方式 电路交换 报文交换 分组交换[数据报方式,虚电路方式] 三.电路交换 eg:电话网络(特点:**独占资源,**即使两个人不说话,链接也不会被别 ...

  2. java opencsv解析csv文件

    记一次使用opencsv解析csv文件时碰到的坑 最近在开发过程中需要解析csv文件,公司用的解析工具是opencsv,在根据opencsv的官方文档去解析时发现csv文件中含有繁体字,使用其自带的C ...

  3. 题解 洛谷 P3734 【[HAOI2017]方案数】

    可以先考虑没有障碍物的情况,设计状态\(f_{i,j,k}\),表示到达坐标 \((x,y,z)\)二进制下,\(x\)有\(i\)位,\(y\)有\(j\)位,\(z\)有\(k\)位的方案数. 得 ...

  4. JMS资源文件下载列表

    网关程序(Gateway) https://files.cnblogs.com/files/IWings/Gateway.zip 网关裁判程序(GatewayReferee) https://file ...

  5. Jarvisoj-web Login

    题目入口: http://web.jarvisoj.com:32772/ 有个登陆框,随便提交参数然后bp抓包 get到了一个Hint,给了sql查询的语句 select * from `admin` ...

  6. iPhone截长图的方法

    iPhone手机暂没有长图截取功能,所以我们只能通过别的方式进行长图截取. (2020年4月10日更新) ios13目前可以截长图了,不过只能在Safari中进行长图截取,而且存储形式为pdf格式,下 ...

  7. vue.js全局组件和局部组件区别

    在id=‘#app’,加入<pl>标签,但也访问不了局部chil组件: 在id=‘#div0’,加入<as>标签,但能访问到全局组件

  8. java基础(11)--封装

    一.java面向对象三大特别: 1.封装 2.继承 3.多态   二.封装的作用 1.属性私有化(private) 2.对外提供简单的入口 如公开的set()与get()方法,并且都不带static ...

  9. 官宣!AWS Athena正式可查询Apache Hudi数据集

    1. 引入 Apache Hudi是一个开源的增量数据处理框架,提供了行级insert.update.upsert.delete的细粒度处理能力(Upsert表示如果数据集中存在记录就更新:否则插入) ...

  10. mapstruct 实体转换及List转换,@Mapper注解转换

    本文参考 https://blog.csdn.net/u012373815/article/details/88367456 主要是为了自己使用方便查询. 这些都是我平时用到了,大家有什么好方法或者有 ...