Kitex+Hertz+Gorm+Etcd完整实现 | 青训营笔记

276 阅读1分钟

这是我参与「第五届青训营」笔记创作活动的第6天

大项目基础架构图

大项目基础架构.png

今天完成了api+user部分的3个功能,分别是用户注册、用户登录、用户信息获取。并且使用了docker环境和cmd+dal+idl+kitex_gen+pkg的项目架构模式,以下对几个重难点作记录说明:

1. Kitex的router文件夹修改

user部分的3个功能,并不都需要用户携带token进行认证。用户注册和用户登录功能不需要携带token,而用户信息获取需要携带功能。因此,在将jwt用作路由中间件时,需要将这两类功能的路由中间件分开设置,如下:

X}3ZJU82E7(NQ`U951UCA.png

并给用户信息获取功能添加jwt路由中间件:

QQ图片20230219172316.png

这样就能实现,当客户端向/douyin/user接口发送GET请求时,jwt中间件会自动获取传入的token值并做验证。只有验证token有效,才会进行后续操作;反之,直接返回token失效。

2. 对app.RequestContext携带内容进行添加和获取

因为用户登录后需要返回token和user_id,而在Hertz的jwt中间件的LoginHandle函数中,只能自主实现LoginResponse函数,这其中就无法获取到user_id。因此,我在Authenticator函数中将调用rpc服务获得的user_id值直接存储在了c *app.RequestContext中。这样一来,自主实现的LoginResponse函数就可以从app.RequestContext中Get到user_id,从而返回到客户端。

Authenticator: func(ctx context.Context, c *app.RequestContext) (interface{}, error) {
        var err error
        var req api.DouyinUserLoginRequest
        if err = c.BindAndValidate(&req); err != nil {
                return "", jwt.ErrMissingLoginValues
        }
        if len(req.Username) == 0 || len(req.Password) == 0 {
                return "", jwt.ErrMissingLoginValues
        }

        user_id, err := rpc.CheckUser(context.Background(), &user.CheckUserRequest{
                Username: req.Username,
                Password: req.Password,
        })

        c.Set("user_id", user_id)
        return user_id, err
},
LoginResponse: func(ctx context.Context, c *app.RequestContext, code int, token string, expire time.Time) {
        user_id, _ := c.Get("user_id")
        c.JSON(http.StatusOK, utils.H{
                "status_code": errno.Success.ErrCode,
                "status_msg":  errno.Success.ErrMsg,
                "user_id":     user_id,
                "token":       token,
                // "expire":      expire.Format(time.RFC3339),
        })
},

3. 功能实现展示

(1) 用户登录功能

image.png

(2) 用户注册功能

image.png

(3) 用户信息获取功能

image.png