当前位置: 首页 > news >正文

C++GO语言微服务之用户信息处理

目录

01 01-微服务实现用户注册-微服务端-上

02 02-微服务实现用户注册-微服务端-下

03 03-微服务实现用户注册-web端

04 04-微服务实现用户注册-web端-流程小结

05 05-获取地域信息-读MySQL写Redis入

06 06-获取地域信息-先查redis-没有读MySQL写入

01 07-Cookie简介

02 08-Session简介

03 09-Cookie和Session的对比和生成

04 10-Cookie操作练习

05 11-Session的操作练习-上-初始化容器

06 12-Session的操作练习-下-设置属性获取session

07 13-获取手机号密码登录用户-存入session

08 01-修改GetSession函数,完成用户登录

09 02-用户退出登录


01 01-微服务实现用户注册-微服务端-上

# 微服务实现 注册用户

## 微服务端

1.  修改密码本 —— proto 文件

    ```go
    syntax = "proto3";
    
    package go.micro.srv.user;
    
    service User {
        rpc SendSms(Request) returns (Response) {};
        rpc Register(RegReq) returns (Response) {};   // 注册用户
    }
    
    message RegReq {
        string mobile = 1;
        string password = 2;
        string sms_code = 3;
    }
    
    message Request {
        string phone = 1;
        string imgCode = 2;
        string uuid = 3;
    }
    
    message Response {
        string errno = 1;
        string errmsg = 2;
    }
    ```

02 02-微服务实现用户注册-微服务端-下

2. make 编译生成 xxx.micro.go 文件。

3. 修改 service/user/main.go    --- 没有需要修改的

4. 修改 handler/user.go 

    ```go
    // 添加 方法
    func (e *User) Register(ctx context.Context, req *user.RegReq, rsp *user.Response) error {
        return nil
    }
    ```

5. 需要操作,MySQL数据库, 拷贝 web/model/model.go 到  微服务项目中。

03 03-微服务实现用户注册-web端

6. 在 service/user/model/modelFunc.go 中 添加 校验短信验证码函数实现

    ```go
    // 校验短信验证码
    func CheckSmsCode(phone, code string) error {
        // 链接redis
        conn := RedisPool.Get()
    
        // 从 redis 中, 根据 key 获取 Value --- 短信验证码  码值
        smsCode, err := redis.String(conn.Do("get", phone+"_code"))
        if err != nil {
            fmt.Println("redis get phone_code err:", err)
            return err
        }
        // 验证码匹配  失败
        if smsCode != code {
            return errors.New("验证码匹配失败!")
        }
        // 匹配成功!
        return nil
    }

04 04-微服务实现用户注册-web端-流程小结

7.   service/user/model/modelFunc.go 中, 添加函数RegisterUser, 实现 用户注册信息,写入MySQL数据库

    ```go
    // 注册用户信息,写 MySQL 数据库.
    func RegisterUser(mobile, pwd string) error {
        var user User
        user.Name = mobile        // 默认使用手机号作为用户名
    
        // 使用 md5 对 pwd 加密
        m5 := md5.New()            // 初始md5对象
        m5.Write([]byte(pwd))            // 将 pwd 写入缓冲区
        pwd_hash := hex.EncodeToString(m5.Sum(nil))    // 不使用额外的秘钥
    
        user.Password_hash = pwd_hash
    
        // 插入数据到MySQL
        return GlobalConn.Create(&user).Error
    }
    ```

05 05-获取地域信息-读MySQL写Redis入

8. 完成  Register  函数 实现

    ```go
    func (e *User) Register(ctx context.Context, req *user.RegReq, rsp *user.Response) error {
        // 先校验短信验证码,是否正确. redis 中存储短信验证码.
        err := model.CheckSmsCode(req.Mobile, req.SmsCode)
        if err == nil {
    
            // 如果校验正确. 注册用户. 将数据写入到 MySQL数据库.
            err = model.RegisterUser(req.Mobile, req.Password)
            if err != nil {
                rsp.Errno = utils.RECODE_DBERR
                rsp.Errmsg = utils.RecodeText(utils.RECODE_DBERR)
            } else {
                rsp.Errno = utils.RECODE_OK
                rsp.Errmsg = utils.RecodeText(utils.RECODE_OK)
            }
        } else {  // 短信验证码错误
            rsp.Errno = utils.RECODE_DATAERR
            rsp.Errmsg = utils.RecodeText(utils.RECODE_DATAERR)
        }
        return nil
    }
    ```

06 06-获取地域信息-先查redis-没有读MySQL写入

## web 端

1.  拷贝密码本 ——proto

2.  创建 web/utils/utils.go 文件, 封装 函数实现 初始 consul 客户端代码

    ```go
    // 初始化micro
    func InitMicro() micro.Service {
        // 初始化客户端
        consulReg := consul.NewRegistry()
        return micro.NewService(
            micro.Registry(consulReg),
        )
    }
    ```

01 07-Cookie简介

3. 实现 web/controller/user.go 中的 PostRet 函数

    ```go
    // 发送注册信息
    func PostRet(ctx *gin.Context) {
        // 获取数据
        var regData struct {
            Mobile   string `json:"mobile"`
            PassWord string `json:"password"`
            SmsCode  string `json:"sms_code"`
        }
        ctx.Bind(&regData)
    
        // 初始化consul
        microService := utils.InitMicro()
        
        // 初始化客户端
        microClient := userMicro.NewUserService("go.micro.srv.user", microService.Client())
    
        // 调用远程函数
        resp, err := microClient.Register(context.TODO(), &userMicro.RegReq{
            Mobile:regData.Mobile,
            SmsCode:regData.SmsCode,
            Password:regData.PassWord,
        })
        if err != nil {
            fmt.Println("注册用户, 找不到远程服务!", err)
            return
        }
        // 写给浏览器
        ctx.JSON(http.StatusOK, resp)
    }
    ```

02 08-Session简介

4. 测试:

    - consul 启动
    - getCaptcha 服务启动  --- 12341
    - user 服务启动  --- 12342
    - web 启动  --- 8080
    - 浏览器测试,注册流程。
        - 成功:
            - 界面跳转。
            - 查询 MySQL数据库, 多一条用户信息。

03 09-Cookie和Session的对比和生成

# 获取地域信息

## 导入 SQL脚本

1. 将 home.sql 保存至 Linux 系统。建议放 家目录。
2. 登录 MySQL数据库。选择数据库: use  search_house;
3. 执行 source  /home/itcast/home.sql  ——  运行 脚本文件。向表插入数据。

04 10-Cookie操作练习

## web端实现

1. 在 web/main.go 中,添加路由, 设置回调。

    ```go
    r1.GET("/areas", controller.GetArea)
    ```

2. 在 web/controller/use.go 中, 添加 GetArea() 函数。

    ```go
    func GetArea(ctx *gin.Context)  {
    }
    ```

05 11-Session的操作练习-上-初始化容器

3. 从数据库获取数据,提高用户感受的常见方法:先查缓存, 缓存没有查MySQL, 写入redis缓存。

    ```go
    // 测试实现:
    // 获取地域信息
    func GetArea(ctx *gin.Context)  {
        // 先从MySQL中获取数据.
        var areas []model.Area
    
        model.GlobalConn.Find(&areas)
    
        // 再把数据写入到 redis 中.
        conn := model.RedisPool.Get()        // 获取链接
        conn.Do("set", "areaData", areas)
    
        resp := make(map[string]interface{})
    
        resp["errno"] = "0"
        resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
        resp["data"] = areas
    
        ctx.JSON(http.StatusOK, resp)
    }
    ```

06 12-Session的操作练习-下-设置属性获取session

4. 测试:登录 redis ,指定 --raw 参数,显示中文。

    ```shell
    itcast@ubuntu:~$ redis-cli -h 192.168.6.108 -p 6379 --raw
    192.168.6.108:6379> keys *
    areaData
    hello
    itcast
    192.168.6.108:6379> get areaData
    [{1 东城区 []} {2 西城区 []} {3 朝阳区 []} {4 海淀区 []} {5 昌平区 []} {6 丰台区 []} {7 房山区 []} {8 通州区 []} {9 顺义区 []} {10 大兴区 []} {11 怀柔区 []} {12 平谷区 []} {13 密云区 []} {14 延庆区 []} {15 石景山区 []}]
    192.168.6.108:6379> 
    
    ```

5. 思考:按如上方法存储数据到 Redis 中 `conn.Do("set", "areaData", areas)`, 将来 使用 Do 获取数据时!不好获取!没有对应的 回复助手函数来完成 “类型断言”。 —— 重新选择 存储 redis 的方法: 将 数据转换成 josn 字节流存储。 

07 13-获取手机号密码登录用户-存入session

![1582438662615](课堂笔记-07.assets/1582438662615.png)

6.  重新实现获取地域信息, 没数据,读MySQL,写redis;有数据,直接读 redis

    - 强调:写入 Redis 中的数据 —— 序列化后的字节流数据。

    ```go
    // 获取地域信息
    func GetArea(ctx *gin.Context) {
        // 先从MySQL中获取数据.
        var areas []model.Area
    
        // 从缓存redis 中, 获取数据
        conn := model.RedisPool.Get()
        // 当初使用 "字节切片" 存入, 现在使用 切片类型接收
        areaData, _ := redis.Bytes(conn.Do("get", "areaData"))
        // 没有从 Redis 中获取到数据
        if len(areaData) == 0 {
    
            fmt.Println("从 MySQL 中 获取数据...")
            model.GlobalConn.Find(&areas)
            // 把数据写入到 redis 中. , 存储结构体序列化后的 json 串
            areaBuf, _ := json.Marshal(areas)
            conn.Do("set", "areaData", areaBuf)
    
        } else {
            fmt.Println("从 redis 中 获取数据...")
            // redis 中有数据
            json.Unmarshal(areaData, &areas)
        }
    
        resp := make(map[string]interface{})
    
        resp["errno"] = "0"
        resp["errmsg"] = utils.RecodeText(utils.RECODE_OK)
        resp["data"] = areas
    
        ctx.JSON(http.StatusOK, resp)
    }
    ```

08 01-修改GetSession函数,完成用户登录

7. 测试:
   
    1. GoLand 中 借助输出,看到 展示的数据来源。 



# Cookie 和 Session

## Cookie 和 Session简介

- http协议,有 3 个版本:
    - http/1.0 版:无状态,短连接。
    - http/1.1 版:可以记录状态。—— 默认支持。
    - http/2.0 版:可以支持长连接。 协议头:Connection: keep-alive 。

09 02-用户退出登录

### Cookie

- 最早的 http/1.0 版,提供 Cookie 机制, 但是没有 Session。
- Cookie 作用:一定时间内, 存储用户的连接信息。如:用户名、登录时间 ... 不敏感信息。
- Cookie 出身:http自带机制。Session不是!
- Cookie 存储:Cookie 存储在 客户端 (浏览器) 中。—— 浏览器可以存储数据。少
    - 存储形式:key - value
    - 可以在浏览器中查看。
    - Cookie 不安全。直接将数据存储在浏览器上。

### Session

- ”会话“:在一次会话交流中,产生的数据。不是http、浏览器自带。
- Session 作用:一定时间内, 存储用户的连接信息。
- Session 存储:在服务器中。一般为 临时 Session。—— 会话结束 (浏览器关闭) , Session被干掉!

### 对比 Cookie 和 Session

1.  Cookie 存储在 浏览器, 在哪生成呢?
2.  Session 存储在 服务器,在哪生成呢?
3.  什么时候生成Cookie , 什么时候生成 Session?

![1582441308868](课堂笔记-07.assets/1582441308868.png)

相关文章:

  • 深圳SMT贴片加工厂制造流程解析
  • 4.分布式锁
  • Pale Moon:速度优化的Firefox定制浏览器
  • vue访问后端接口,实现用户注册
  • 【金仓数据库征文】_金仓数据库在金融行业的两地三中心容灾架构实践
  • Linux 内核链表宏的详细解释
  • 前端开发实战:用React Hooks优化你的组件性能
  • 缓存理论到实战:技术选型与七层架构设计
  • Windows 系统 - Trae 内 终端 无法使用 node (重新配置 nodejs 路径)
  • RT-Thread 深入系列 Part 7:RT-Thread vs 其他 RTOS 对比与选型指南
  • 图像处理篇---opencv实现坐姿检测
  • Kotlin高阶函数多态场景条件判断与子逻辑
  • 腾讯多模态定制化视频生成框架:HunyuanCustom
  • C语言的中断 vs Java/Kotlin的异常:底层机制与高级抽象的对比
  • android HashMap和List该如何选择
  • 05 mysql之DDL
  • 通俗的理解MFC消息机制
  • 基于小波神经网络(WNN)的回归预测模型【MATLAB】
  • Flutter PIP 插件 ---- 为iOS 重构PipController, Demo界面,更好的体验
  • 大学之大:悉尼科技大学2025.5.10
  • 一生要出片的年轻人,买爆相机
  • 名帅大挪移提前开启,意属皇马的阿隆索会是齐达内第二吗
  • 招商蛇口:今年前4个月销售额约498.34亿元
  • 英国和美国就关税贸易协议条款达成一致
  • 上交现场配乐4K修复版《神女》:默片巅峰有了新的打开方式
  • 万里云端遇见上博--搭乘“上博号”主题飞机体验记