返回

go-zero 快速实战:揭秘 JWT 鉴权机制

后端







## 前言

在现代软件开发中,鉴权是一个至关重要的安全机制,它确保只有经过授权的用户才能访问系统资源。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 来快速生成数据模型代码、服务端代码和客户端代码。希望本文对您有所帮助。