前面我们分享了 go-zero 的快速实战以及日志组件的剖析,本次我们来实战使用 go-zero jwt 鉴权
本次文章主要是分享关于 go-zero 中 jwt 的使用方式,会以一个 demo 的方式来进行实战,对于使用 goctl 工具以及安装细节就不在赘述,有需要的话可以查看:
本次文章主要分为如下几个部分:
关于 jwt 鉴权的细节和原理,感兴趣的朋友可以查看历史文章:
那么我们如何识别什么时候需要使用 jwt 呢?
例如某个系统通过例如账号密码登录之后,后台会生成一个 jwt,这个用户在这个系统之后的任何操作,都会去校验这个 jwt,就不需要用户操作系统内其他模块的时候,还去进行一次登录
当然,这是需要我们做好设定,这个 jwt 针对哪一些路由可以使用,从而允许用户访问该令牌允许的路由,服务和资源
因为 jwt 可以与各方进行安全的传输,内部使用了签名算法,公钥加密,私钥解密,而且 jwt 的数据各种中有标头,有效载荷,以及其他的签发时间,过期时间,颁发人等等,可以用来校验信息是否被篡改了
话不多说,咱们就来开始实战吧,先来给自己提一个需求:
那么,根据上述需求,显然,咱们会使用到数据库,本次这里咱们仍然使用 mysql 进行演示,并且会涉及到用户表和图书表
我们可以现在创建一下这两张表
user.sql
CREATE TABLE `user`
(
`stu_id` varchar(255) NOT NULL COMMENT 'stu_id',
`name` varchar(255) NOT NULL COMMENT 'name',
`password` varchar(255) NOT NULL COMMENT 'password',
`gender` varchar(255) NOT NULL COMMENT 'gender',
PRIMARY KEY(`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
复制代码
stu_id | 学号 |
---|---|
name | 姓名 |
password | 密码 |
gender | 性别 |
book.sql
CREATE TABLE `book`
(
`book_id` varchar(255) NOT NULL COMMENT 'stu_id',
`name` varchar(255) NOT NULL COMMENT 'name',
`count` INTEGER (255) NOT NULL COMMENT 'password',
PRIMARY KEY(`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
复制代码
book_id | 图书 id |
---|---|
name | 图书名称 |
count | 图书剩余数量 |
咱们可以向表中插入一些 demo 数据,便于后续使用
insert into book(book_id,name,count)values("000001","kubernetes in action",99);
insert into book(book_id,name,count)values("000002","effective go",88);
insert into book(book_id,name,count)values("000003","穷爸爸富爸爸",21);
insert into user(stu_id,name,password,gender)values("13141549", "小胖", "Aa123123", "男");
insert into user(stu_id,name,password,gender)values("15161766", "阿强", "6r*,oo", "男");
insert into user(stu_id,name,password,gender)values("1325590", "marry", "123456", "女");
复制代码
先来看看基本的代码目录
新建目录
mkdir my_test_demo/my_book_sys/book/api -p
mkdir my_test_demo/my_book_sys/book/model -p
mkdir my_test_demo/my_book_sys/user/api -p
mkdir my_test_demo/my_book_sys/user/rpc -p
mkdir my_test_demo/my_book_sys/user/model -p
cd my_test_demo
go mod init my_test_demo
go mod tidy
复制代码
编写 api 文件 并生成 go 代码
book.api
定义 book api
GET /search/do 查询书籍接口,使用 jwt: Auth
进行标识
user.api
定义 user api
定义 POST /user/login 接口
\
使用工具将上述 api 生成 go 对应的代码
cd my_test_demo/my_book_sys/book/api
vim book.api
goctl api go -api book.api -dir .
cd my_test_demo/my_book_sys/user/api
vim user.api
goctl api go -api user.api -dir .
复制代码
book.sql
拷贝到 my_test_demo/my_book_sys/book/model
下my_test_demo/my_book_sys/user/model
下生成数据库相关的 go 代码文件
cd my_test_demo/my_book_sys/book/model
goctl model mysql ddl -src book.sql -dir .
cd my_test_demo/my_book_sys/user/model
goctl model mysql ddl -src user.sql -dir .
复制代码
这个时候,咱们就已经完成了大部分的准备工作,接下来我们来查看一下代码目录
添加数据库配置和 jwt 相关配置
User 部分
my_test_demo/my_book_sys/user/api/etc/user-api.yaml
,加上数据库配置和 Auth 配置my_test_demo/my_book_sys/user/api/internal/config/config.go
增加配置对应的数据结构my_test_demo/my_book_sys/user/api/internal/svc/servicecontext.go
,以及补充 NewServiceContext 的实现my_test_demo/my_book_sys/user/api/internal/logic/loginlogic.go
,大体逻辑如下my_test_demo/my_book_sys/user/model/usermodel_gen.go
文件中添加了数据库操作的 FindOneByName 方法此处的 model 方法可以加在 my_test_demo/my_book_sys/user/model/usermodel_gen.go
Book 部分
my_test_demo/my_book_sys/book/api/etc/book-api.yaml
,加上数据库配置和 Auth 配置其中 AccessSecret 和 AccessExpire 的字段名和值保持和上述 user 路径下的内容一致
Name: search-api
Host: 0.0.0.0
Port: 9001
DataSource: root:123456@tcp(localhost:3306)/test_demo
Auth:
AccessSecret: secretoooppppoooo
AccessExpire: 3600
复制代码
my_test_demo/my_book_sys/book/api/internal/config/config.go
type Config struct {
rest.RestConf
DataSource string
Auth struct {
AccessSecret string
AccessExpire int64
}
}
复制代码
my_test_demo/my_book_sys/book/api/internal/svc/servicecontext.go
,以及补充 NewServiceContext 的实现my_test_demo/my_book_sys/book/api/internal/logic/searchlogic.go
,大体逻辑如下上述代码中 l.svcCtx.BookHttpModel.FindOneByName 是我们自定义修改了 model 下的文件内容,新增 FindOneByName 方法 ,修改 my_test_demo/my_book_sys/book/model/bookmodel_gen.go
验收成果
咱们分别进入到项目对应的 api 路径下,启动服务
终端1:
cd my_test_demo/my_book_sys/book/api
go run search.go
复制代码
终端2:
cd my_test_demo/my_book_sys/user/api
go run user.go
复制代码
终端3:
curl -i -X GET \
'http://localhost:9001/search/do?name=effective%20go'
复制代码
// post 用户登录
curl -i -X POST http://localhost:9002/user/login -H 'Content-Type: application/json' -d '{
"username":"小胖",
"password":"Aa123123"
}'
复制代码
可以看到是登录成功了,且服务端给我们返回了对应的 jwt token,接下来咱们执行第一步,请求查询一下数据的数量
// get 书籍
curl -i -X GET \
'http://localhost:9001/search/do?name=effective%20go' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjA5NzMwNDEsImlhdCI6MTY2MDk2OTQ0MSwic3R1SWQiOiIxMzE0MTU0OSJ9.Jae_5GPr-xuB2mfqospfisV93ReUnGTZJ87WsIQ-bhE'
复制代码
很明显,此处的鉴权机制 ok,鉴权完毕之后,正确查询数据库,查询到我们期望的书籍剩余数量
兄弟们,动起手来吧,先来应用 go-zero 的 jwt ,再去看 go-zero 的实际源码细节,很快就能明白
具体的源码地址可以查看:github.com/qingconglai…
至此,本篇内容结束
感谢阅读,欢迎交流,点个赞,关注一波 再走吧
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
\
\
// get 书籍
curl -i -X GET \
'http://localhost:9001/search/do?name=effective%20go' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjA5NzMwNDEsImlhdCI6MTY2MDk2OTQ0MSwic3R1SWQiOiIxMzE0MTU0OSJ9.Jae_5GPr-xuB2mfqospfisV93ReUnGTZJ87WsIQ-bhE'
// post 用户登录
curl -i -X POST http://localhost:9002/user/login -H 'Content-Type: application/json' -d '{
"username":"小胖",
"password":"Aa123123"
}'