【CloudWeGo】字节跳动 Golang 微服务框架 Hertz 集成 Session

Hello,大家好!我是千羽。

今天我们将探讨如何在字节跳动的 Golang 微服务框架 Hertz 中集成 session 功能。
通过实践,我们会逐步了解如何在项目中完成从环境搭建到接口调试的流程。
一、Hertz 项目目录结构
以下是 Hertz 项目的基本目录结构,展示了如何集成 session:
├── Makefile # 定义项目的自动化任务脚本
├── README.md
├── biz
│ ├── dal
│ │ ├── init.go
│ │ └── mysql
│ │ ├── init.go # 连接信息
│ │ └── user.go # 包含对用户数据在 MySQL 中的操作
│ ├── handler
│ │ ├── ping.go
│ │ └── user
│ │ └── user_service.go
│ ├── model
│ │ └── user
│ │ └── user.go
│ ├── mw
│ │ ├── csrf.go # 跨域
│ │ └── session.go
│ └── router
│ ├── register.go
│ └── user
│ ├── middleware.go
│ └── user.go
├── docker-compose.yml # 定义和运行多个 Docker 容器的配置文件
├── go.mod
├── go.sum
├── idl
│ └── user.thrift
├── images
│ ├── index-page.png
│ ├── login-page.png
│ └── register-page.png
├── main.go
├── pkg
│ ├── consts
│ │ └── consts.go
│ ├── render
│ │ └── render.go
│ └── utils
│ └── utils.go
├── router.go
├── router_gen.go
二、运行项目
Step 1:启动 MySQL 容器
首先,使用 Docker 启动 MySQL 容器:
cd bizdemo/hertz_session && docker-compose up
运行后,您会看到如下输出:

docker运行mysql
Step 2:编译并运行项目
在终端运行以下命令来启动项目:
cd bizdemo/hertz_session && go run main.go
看到以下日志就说明启动成功了:
2024/11/12 23:51:05.802956 engine.go:396: [Info] HERTZ: Using network library=netpoll
2024/11/12 23:51:05.807942 transport.go:115: [Info] HERTZ: HTTP server listening on address=[::]:8888

项目启动
三、API 接口调试

  1. /register 用户注册接口
    请求 URL: http://localhost:8888/register.html
    请求参数:
    {
    “username”: “hertz_session”,
    “email”: “1122@qq.com”,
    “password”: “password”
    }
    响应结果:

注册成功后,在数据库中可以看到新用户记录:

数据库查询

  1. /login 用户登录接口
    请求 URL: http://localhost:8888/login.html
    输入用户名和密码,成功后返回登录结果:

登录成功

  1. /ping 接口
    请求 URL: http://localhost:8888/ping
    响应结果:
    {
    “message”: “pong”
    }

接口响应
四、代码解析
5.1 根据 user.thrift 生成接口代码
以下是定义的 UserService 服务接口代码:
namespace go user

struct BaseResp {
1: i64 code
2: string message
}

struct RegisterRequest {
1: string username (api.form=”username”, api.vd=”(len($) > 0 && len($) < 128); msg:’Illegal format'”) 2: string password (api.form=”password”, api.vd=”(len($) > 0 && len($) < 128); msg:’Illegal format'”) 3: string email (api.form=”email”, api.vd=”(len($) > 0 && len($) < 128) && email($); msg:’Illegal format'”)
}

struct RegisterResponse {
1: BaseResp baseresp
}

service UserService {
RegisterResponse register(1: RegisterRequest req) (api.post=”/register”)
LoginResponse login(1: LoginRequest req) (api.post=”/login”)
}
5.2 实现用户注册接口
在 router.go 中配置路由:
func Register(r *server.Hertz) {
root := r.Group(“/”, rootMw()…)
root.POST(“/login”, append(loginMw(), user.Login)…) root.POST(“/register”, append(_registerMw(), user.Register)…) } 在 user_service.go 中实现 Register 处理函数: func Register(ctx context.Context, c *app.RequestContext) { // 接收注册参数并验证 var registerStruct struct { Username string form:"username" json:"username" Email string form:"email" json:"email" Password string form:"password" json:"password" } // 绑定参数并验证 if err := c.BindAndValidate(®isterStruct); err != nil { c.JSON(http.StatusOK, utils.H{“message”: err.Error(), “code”: http.StatusBadRequest}) return } // 检查用户名和邮箱是否存在 users, err := mysql.FindUserByNameOrEmail(registerStruct.Username, registerStruct.Email) if err != nil || len(users) != 0 { c.JSON(http.StatusOK, utils.H{“message”: “user already exists”, “code”: http.StatusBadRequest}) return } // 创建用户 err = mysql.CreateUsers([]*model.User{{ UserName: registerStruct.Username, Email: registerStruct.Email, Password: utils.MD5(registerStruct.Password), }}) if err != nil { c.JSON(http.StatusOK, utils.H{“message”: err.Error(), “code”: http.StatusBadRequest}) return } c.JSON(http.StatusOK, utils.H{“message”: “success”, “code”: http.StatusOK}) } 5.3 登录实现 在 user_service.go 中实现 Login 函数: func Login( context.Context, c *app.RequestContext) {
var req user.LoginRequest
if err := c.BindAndValidate(&req); err != nil {
c.HTML(http.StatusOK, “login.html”, hutils.H{“message”: err.Error()})
return
}
users, err := mysql.CheckUser(req.Username, utils.MD5(req.Password))
if err != nil || len(users) == 0 {
c.HTML(http.StatusOK, “login.html”, hutils.H{“message”: consts.LoginErr})
return
}
session := sessions.Default(c)
session.Set(consts.Username, req.Username)
_ = session.Save()
c.Redirect(http.StatusMovedPermanently, []byte(“/index.html”))
}
总结:
通过详细的代码示例,逐步实现了基于 Hertz 框架的用户会话管理功能。我们配置了目录结构、引入了数据库存储用户数据,并提供了注册和登录接口,演示了完整的会话创建与管理流程。
通过 session 实现的用户认证逻辑,确保了登录用户的持续访问控制,提升了项目的安全性和用户体验。这一套流程帮助开发者更深入理解 Hertz 框架在实际场景中的应用。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/423739.html

联系我们
联系我们
分享本页
返回顶部