什么是 JWT?
JSON 网络令牌是一种 Internet 标准,用于创建具有可选签名或可选加密的数据,让两方之间安全地表示声明。令牌使用私有秘密或公共/私有密钥进行签名。
简单来讲,就是通过 JWT 机制,让客户端通过一个密钥,把信息进行加密,添加到 HTTP 请求的 Header中,并传给服务端,服务端验证客户的合法性。
请参考 JWT 官网
棘手的问题
实现 JWT 逻辑很简单,网上有很多现成的资料可以参考。我们遇到的棘手问题就是【怎么存储密钥】。
- 代码仓库:泄漏风险高,非常不安全
- 私有密钥管理系统:安全,不过额外多了一个运维工作,要保证此系统不能出错
我们需要的就是一个第三方提供的【安全】,【简单】的密钥提供商。云厂商的 KMS(Key Management System)就可以完美解决这个问题。
各大云厂商都提供 KMS 服务,这里我们以腾讯云 KMS 为例,做个小 Demo。
解决方案
我们将使用 rk-boot/v2 + rk-cloud/tencent/signer + 腾讯云 KMS 快速实现后端 JWT 验证以及签名逻辑。
Demo
在这个 Demo 里,我们会模拟如下场景。提供两个 API,/v1/login & /v1/greeter。
- /v1/login: 登陆 API,服务端会返回 accessToken
- /v1/greeter: 发送的时候,在 HTTP Header 中加入 accessToken,否则请求返回 401
1. 开通腾讯云账户 & 开通 KMS
开通腾讯云账户 是免费的,不过建议往里存个1块钱,否则可能无法在 KMS 中创建密钥。
2.生成云访问密钥 & 创建 KMS 密钥
想要通过代码使用云上的资源,就需要使用到云访问密钥,一般称为 AK/SK,根据下面的文档生成密钥,并且保存,切记不要泄漏这个密钥。
然后,我们就可以登陆控制台,创建用于签名的 RSA 非对称密钥了。腾讯云提供了标准版 & 旗舰版 KMS,旗舰版更安全,就是贵,中小项目使用标准版即可。
这里请选择【非对称签名验签】&【RSA_2048】。rk-cloud/tencent 暂时不支持其他加密算法。
创建成功后,记住 ID,我们在代码里会引用到这个 ID。
3.下载 rk-boot/v2
我们总共下载了3个依赖。
4.配置 boot.yaml
boot.yaml 文件告诉 rk-boot/v2 启动哪些 Gin & KMS 配套的服务。
5.写两个 API
生成 JWT Token 的时候,rk-boot/v2 会远程调用 KMS API 获取签名。验证签名的时候,不会调用 KMS API,rk-boot/v2 会在启动的时候,拉取 Public Key,这样节省了成本。
6. 启动 main.go
7. 验证
第一步,发送 /v1/login 请求,获取 AccessToken
发送 /v1/greeter 请求,并且带着 Authorization Header,记住,AccessToken 前面要加上 [Bearer],这是 JWT 中间件默认会验证的。
如果,发送一个错误的 AccessToken,则会返回 401
rk-boot/v2 介绍
在形容 rk-boot/v2 的时候,一直没有找到一个合适的词语,类似 Go版本的 Spring boot,也类似 Go 进程启动器。当然,功能,完整性,理念等远不及 Spring boot。
暂时还没有想到更好的词汇。不过不耽误介绍其用法和设计理念。
RK 设计理念
在设计 rk-boot/v2 的时候,我们有几个【不做清单】。
- 不创造 RPC 框架
- 不重复造轮子
- 不封装开源 API/函数,保留原生用法
- 不引入小众开源
- 不绑定特定业务
我们想要做的是,让使用者可以通过 YAML 配置文件,以及几行简单代码,一键启动【高标准】Golang 微服务。简单点说,就是在 YAML 文件里,填写几行配置,就能让进程自动提供监控,日志,安全等等附属功能。
整个 RK 系列由3个大部分组成。
如果把实现 Golang 后端微服务比喻成制作一个产品,RK 在其中的作用相当于【材料提供商】,与使用【原生开源材料】不同点在于, 使用者不必考虑和学习如何初始化【原生开源材料】,如何配置,如何进行监控,错误处理。使用者唯一要做的就是,熟悉【原生开源材料】的使用方法,嵌入到代码里使用。 我们希望通过这种方式,节省开发者的时间成本,以及保证代码库的标准性。
RK 插件
RK 的插件我们使用了【节外生枝】的设计理念。对于 RK 来说,流行的开源产品,属于【原料】,这些【原料】通过实现 rk-entry 抽象,就形成了 RK 系列的一个插件,形成【材料】。
rk-boot/v2 会自动识别这些插件,在启动进程的时候,进行相应初始化。
RK 插件列表
目前,rk-boot/v2 还处于萌芽阶段,实现的功能插件比较少,后续会持续迭代,也希望能在开源社区里得到更多的关注,并参与进来。
- Web 框架中间件
- Web 框架启动项