返回
go-zero 快速实战:揭秘 JWT 鉴权机制
后端
2023-10-29 02:36:43
## 前言
在现代软件开发中,鉴权是一个至关重要的安全机制,它确保只有经过授权的用户才能访问系统资源。JWT(JSON Web Token)是一种流行的鉴权机制,它使用一种紧凑的、自包含的 token 来表示用户身份,并使用数字签名来确保 token 的完整性和真实性。
go-zero 是一个简洁高效的 Go 语言微服务开发框架,它提供了丰富的功能和特性,包括 JWT 鉴权支持。在本文中,我们将深入剖析 go-zero 框架的 JWT 鉴权机制,并通过一个真实项目案例,演示如何使用 go-zero 快速搭建一个基于 JWT 的鉴权系统。
## JWT 鉴权简介
JWT 是一种流行的鉴权机制,它使用一种紧凑的、自包含的 token 来表示用户身份,并使用数字签名来确保 token 的完整性和真实性。JWT token 由三部分组成:头部(header)、载荷(payload)和签名(signature)。
* 头部:头部包含有关 JWT 的元数据,例如算法和 token 类型。
* 载荷:载荷包含有关用户身份的信息,例如用户名、电子邮件和角色。
* 签名:签名是使用私钥对头部和载荷进行数字签名生成的,它可以确保 token 的完整性和真实性。
JWT token 可以通过 HTTP 请求头或 cookie 传递。当服务器收到一个 JWT token 时,它会验证 token 的签名,以确保 token 的完整性和真实性。如果 token 验证通过,则服务器将从 token 中提取用户信息,并根据用户信息进行权限控制。
## go-zero JWT 鉴权实战
接下来,我们将通过一个真实项目案例,演示如何使用 go-zero 快速搭建一个基于 JWT 的鉴权系统。
### 项目初始化
首先,我们需要创建一个新的 go-zero 项目。我们可以使用 go-zero 官方提供的脚手架工具来创建项目。
go get github.com/zeromicro/go-zero/tools/goctl
goctl init my-project
### 模型定义
接下来,我们需要定义我们的数据模型。我们可以使用 goctl 的 model 命令来生成数据模型代码。
goctl model mysql -database="user:password@tcp(127.0.0.1:3306)/my_database" -table="user" -dir=.
### 服务端开发
接下来,我们需要开发服务端代码。我们可以使用 goctl 的 service 命令来生成服务端代码。
goctl service my-project -o .
### JWT 鉴权配置
在服务端代码中,我们需要配置 JWT 鉴权。我们可以通过修改 conf/config.yaml 文件来配置 JWT 鉴权。
```yaml
jwt:
secret: "your_secret"
timeout: "30m"
aud: "my_project"
issuer: "my_project"
- secret:JWT token 的签名密钥。
- timeout:JWT token 的有效期。
- aud:JWT token 的受众。
- issuer:JWT token 的颁发者。
路由注册
在服务端代码中,我们需要注册路由。我们可以通过修改 api/internal/router/router.go 文件来注册路由。
package router
import (
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/my-project/api/internal/controller"
"github.com/zeromicro/my-project/api/internal/middleware"
)
func RegisterRoutes(r *rest.Router) {
r.GET("/api/user", middleware.Jwt(), controller.GetUser)
}
- GET /api/user:获取用户信息。
- middleware.Jwt():JWT 鉴权中间件。
JWT 鉴权中间件
接下来,我们需要实现 JWT 鉴权中间件。我们可以创建一个新的 middleware 文件夹,并在其中创建 jwt.go 文件。
package middleware
import (
"context"
"fmt"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/my-project/api/internal/service"
)
type JwtMiddleware struct {
secret string
}
func NewJwtMiddleware(secret string) *JwtMiddleware {
return &JwtMiddleware{
secret: secret,
}
}
func (m *JwtMiddleware) Handle(next rest.HandlerFunc) rest.HandlerFunc {
return func(c rest.Context) {
token := c.Request.Header.Get("Authorization")
if token == "" {
c.JSON(401, map[string]interface{}{
"message": "unauthorized",
})
return
}
claims, err := service.NewJwtService().ParseToken(m.secret, token)
if err != nil {
c.JSON(401, map[string]interface{}{
"message": "invalid token",
})
return
}
ctx := context.WithValue(c.Request.Context(), "claims", claims)
next(rest.WithContext(c, ctx))
}
}
- NewJwtMiddleware():创建 JWT 鉴权中间件。
- Handle():中间件处理函数。
- ParseToken():解析 JWT token。
客户端开发
接下来,我们需要开发客户端代码。我们可以使用 goctl 的 client 命令来生成客户端代码。
goctl client go my-project -o .
JWT 鉴权使用
在客户端代码中,我们需要使用 JWT 鉴权。我们可以通过调用 client/jwt.go 中的 NewJwtClient() 函数来创建一个 JWT 客户端。
package jwt
import (
"github.com/zeromicro/my-project/api/client/user"
)
type JwtClient struct {
client *user.UserService
}
func NewJwtClient(secret, host string) *JwtClient {
client := user.NewUserServiceClient(host)
return &JwtClient{
client: client,
}
}
func (c *JwtClient) GetUser(ctx context.Context, req *user.GetUserRequest) (*user.User, error) {
return c.client.GetUser(ctx, req)
}
- NewJwtClient():创建一个 JWT 客户端。
- GetUser():获取用户信息。
运行项目
最后,我们可以运行项目。我们可以使用以下命令来运行项目:
go run main.go
总结
在本文中,我们深入剖析了 go-zero 框架的 JWT 鉴权机制,并通过一个真实项目案例,演示了如何使用 go-zero 快速搭建一个基于 JWT 的鉴权系统。我们学习了如何使用 JWT 进行用户身份认证、如何验证 JWT token、以及如何在 go-zero 中使用 JWT 进行权限控制。我们还学习了如何使用 goctl 来快速生成数据模型代码、服务端代码和客户端代码。希望本文对您有所帮助。