【Gin-Web】Bluebell社区项目梳理1:注册业务、登录业务流程及代码

news/2025/2/22 6:06:46
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

本文目录

  • 一、Web的CLD分层架构、
  • 二、注册业务流程
  • 三、登录业务流程
  • 四、Token认证模式
    • 基于Cookie和Seesion的认证模式
  • 五、分布式ID生成与雪花算法

一、Web的CLD分层架构、

一般Web项目可以看作是CLD架构,也就是图中所示,Controller+Logic+DAO层,主要如下图所示。
在这里插入图片描述

二、注册业务流程

首先在main.go中注册一个全局的路由。

在这里插入图片描述
SetupRouter中找注册业务的路由,然后进入controller层的SignupHandler方法。

在这里插入图片描述

接着看看SignupHandler的处理流程。

在这里插入图片描述
前端发来一个字符串,我们封装在models里面。
在这里插入图片描述

binding:"required": 这是用于数据验证的标签。required 表示该字段是必填的,如果用户没有提交 username,验证会失败。

eqfield=Password: 表示确认密码必须与 Password 字段的值相等。如果用户提交的密码和确认密码不一致,验证会失败。

来看处理请求参数错的代码:
在这里插入图片描述
首先尝试将请求的 JSON 数据绑定到结构体 fo 中,如果绑定过程中出现错误,会记录一条错误日志并进一步判断错误类型。如果错误不是 validator.ValidationErrors 类型,说明是普通的参数错误,直接返回一个通用的参数错误响应;但如果错误是 validator.ValidationErrors 类型,则会将验证错误翻译成更易读的错误消息,并返回带有具体错误信息的响应。

然后接下来就是开始注册了,也就是对应的当我们处理路由,进行完参数校验之后,就开始处理逻辑Service/Logic了。

在这里插入图片描述
来看看Logic.SighnUp的代码。
在这里插入图片描述

首先检查指定用户名是否已经存在于数据库中。它通过执行 SQL 查询统计用户名匹配的记录数,如果查询失败则直接返回错误;如果查询成功且记录数大于零,说明用户已存在,函数返回一个自定义错误提示“用户已存在”;如果记录数为零,则表示用户不存在,函数返回 nil,表示检查通过。

在这里插入图片描述

然后就是生成唯一的用户ID,并且创建一个User实例,然后存进数据库中。

生成唯一的用户ID是通过雪花算法来的。如下所示。

在最开始的main.go函数中就会初始化了。

在这里插入图片描述

下面是对应的算法。

在这里插入图片描述

time.Parse 函数用于将字符串解析为 time.Time 类型的时间对象,而 “2006-01-02” 是 Go 语言中时间格式化的标准模板字符串。

基于索尼雪花算法(Sonyflake)的全局唯一 ID 生成器的初始化和使用逻辑。Init 函数用于初始化 Sonyflake,它接收一个机器 ID 并设置为全局变量 sonyMachineID,同时定义了一个起始时间(2022年2月9日)作为 Sonyflake 的基准时间。通过 sonyflake.Settings 配置结构体,将起始时间和机器 ID 设置传递给 Sonyflake,并尝试创建一个新的 Sonyflake 实例。如果初始化成功,sonyFlake 将被赋值为这个实例,否则返回错误。

最后就是向数据库插入数据了。
在这里插入图片描述
这里我们对密码进行了md5加密再存进系统中去。

在这里插入图片描述
首先创建一个新的 MD5 哈希对象 h。MD5 是一种广泛使用的哈希算法,它将任意长度的输入数据转换为一个固定长度(128 位)的哈希值。然后将一个名为 secret 的字符串转换为字节切片,并写入到哈希对象中。secret 通常用于为哈希过程添加额外的安全性,类似于“盐”(salt)的作用,防止直接对原始数据进行哈希。

h.Sum(data)将 data 写入到哈希对象 h 中,并计算最终的哈希值。Sum 方法会返回一个字节切片,表示哈希结果。hex.EncodeToString将哈希结果(字节切片)转换为十六进制字符串。这是因为哈希值通常是一个二进制字节序列,而十六进制字符串更易于存储和传输。

三、登录业务流程

登录功能也是一样的,首先前端通过HTTP发送一个登录请求,然后后端的Controller是服务的入口,处理路由,进行参数校验,然后请求转发。接着继续交给Logic层,然后Logic层负责处理业务逻辑,最后到DAO层进行数据存储的相关功能。

通过POST请求到login中。
在这里插入图片描述

然后转到LoginHandler中。

在这里插入图片描述
把前端传来的参数绑定到定义好的LoginForm表单数据模型中,然后进行参数校验和解析。

在这里插入图片描述
在这里我们对错误进行了封装,首先来看看code业务状态码的封装,后续直接调用即可。

在这里插入图片描述

	if err := c.ShouldBindJSON(&u); err != nil {
		// 请求参数有误,直接返回响应
		zap.L().Error("Login with invalid param", zap.Error(err))
		// 判断err是不是 validator.ValidationErrors类型的errors
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			// 非validator.ValidationErrors类型错误直接返回
			ResponseError(c, CodeInvalidParams) // 请求参数错误
			return
		}
		// validator.ValidationErrors类型错误则进行翻译
		ResponseErrorWithMsg(c, CodeInvalidParams, removeTopStruct(errs.Translate(trans)))
		return
	}

如果 err 不是 validator.ValidationErrors类型,说明这是一个非验证错误(例如 JSON 格式错误或绑定失败)。此时直接调用 ResponseError 函数,返回状态码 CodeInvalidParams(请求参数错误),并结束函数执行。

如果 err 是 validator.ValidationErrors 类型,则调用 errs.Translate(trans) 方法将验证错误翻译成用户可读的错误信息。trans 是一个翻译器,用于支持国际化。removeTopStruct 函数用于移除错误消息中可能包含的结构体名称,使错误信息更简洁。然后调用 ResponseErrorWithMsg 函数返回状态码 CodeInvalidParams,并附带具体的错误信息。

这里是李文周老师的对validator库参数校验若干实用技巧:https://www.liwenzhou.com/posts/Go/validator-usages/

然后看看Login的函数逻辑。

在这里插入图片描述
然后在DAO层的login进行数据库登录验证。
在这里插入图片描述

四、Token认证模式

基于Cookie和Seesion的认证模式

HTTP是无状态协议,一次请求结束之后,下次在发送请求,服务器就不知道是谁发来的,这里需要注意的是,同一个IP不代表同一个用户,在Web应用中,用户的认证和鉴权非常重要。

接下来先讲讲Cookie Session模式。

流程图很明显了,但是存在一定的问题。

服务端需要存储session,并且由于Sesion需要经常快速查找,通常存储在内存或内存数据库中,同时在线用户较多时需要占用大量的服务器资源。
当需要扩展时,创建Session的服务器可能不是验证Session的服务器,所以还需要将所有Session单独存储并共享。
由于客户端使用Cookie存储SessionID,在跨域场景下需要进行兼容性处理,同时这种方式也难以防范CSRF攻击。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这个时候可以通过Token进行处理,比如下面的流程实例。

基于Token的无状态会话管理方式,就是服务端可以不再存储信息,甚至是不存储session。客户端来保存token,然后访问需要认证的接口时在URL参数或者HTTP请求的Header头部中加入Token,服务端就可以通过解码Token进行授权了,然后返回给客户端需要的数据。

在这里插入图片描述

五、分布式ID生成与雪花算法

主要就是四个特点,然后后面对系统分库分表了之后,也可以以时间顺序对消息进行排序。

在这里插入图片描述
然后就是雪花算法。
在这里插入图片描述
在项目中我们用了索尼的雪花算法,思路和索尼算法不同,但是位的分配上稍有不同。

在这里插入图片描述
所以其实现代码比较简单,就如上面流程梳理的图所示。


http://www.niftyadmin.cn/n/5861734.html

相关文章

图数据库Neo4j面试内容整理-建模实践

在 Neo4j 中进行图数据建模(Graph Modeling)是设计和构建高效图数据库系统的关键。图数据库与关系型数据库不同,图数据建模强调的是如何通过节点、关系、标签和属性来表示和组织数据之间的复杂联系。因此,图数据库的建模过程不仅需要理解数据本身,还需要考虑查询的效率和扩…

ncDLRES:一种基于动态LSTM和ResNet的非编码RNA家族预测新方法

现有的计算方法主要分为两类:第一类是通过学习序列或二级结构的特征来预测ncRNAs家族,另一类是通过同源序列之间的比对来预测ncRNAs家族。在第一类中,一些方法通过学习预测的二级结构特征来预测ncRNAs家族。二级结构预测的不准确性可能会导致…

C++ 设计模式-解释器模式

数学表达式解释器 示例需求 支持数字、变量、加减乘除运算支持函数调用(如 max(2,3))能够处理嵌套表达式(如 (x + 5) * max(y,10))完整代码实现 #include <iostream> #include <memory> #include <unordered_map> #include <vector> #include &l…

工业级无人机手持地面站技术详解

工业级无人机手持地面站是无人机系统的核心组成部分&#xff0c;它集控制、通信、数据处理于一体&#xff0c;为无人机的安全飞行和任务执行提供全面支持。以下是对工业级无人机手持地面站技术的详细解析&#xff1a; 一、硬件构成 1. 处理器与操作系统&#xff1a; 工业级手…

清华大学102页PPT 《deepseek从入门到精通》

最近有一份资料传疯了——《DeepSeek&#xff1a;入门到精通》&#xff0c;据说是清华大学的高材生出品的。 没来及的细看&#xff0c;扫了一眼&#xff0c;感觉质量杠杠滴&#xff01;不亏是高材生。文件也整理好了&#xff0c;自取&#xff01; DeepSeek从入门到精通完整版手…

Elasticsearch实战应用:从“搜索小白”到“数据侦探”的进阶之路

引言&#xff1a;Elasticsearch——数据世界的“福尔摩斯” 大家好&#xff0c;今天我们要聊的是一个在数据世界中扮演“福尔摩斯”角色的工具——Elasticsearch。如果你曾经为海量数据的搜索和分析头疼不已&#xff0c;那Elasticsearch就是你的救星&#xff01;它不仅能帮你快…

GoLang 协程泄漏的原因可能是什么?

今天面试遇到的一个问题&#xff0c;记录一下 文章目录 1. 无限循环3. 等待不可能发生的条件4. 未正确关闭通道&#xff08;Channel&#xff09;5. 错误的Context管理6. 资源未正确释放7. 全局变量或数据结构的意外引用8. 协程内部发生Panic9. HTTP请求未关闭响应体10. 循环引用…

深入学习 XML:语法、约束、解析及相关技术

一、引言 在当今的软件开发领域&#xff0c;数据的存储和交换至关重要。XML&#xff08;Extensible Markup Language&#xff09;作为一种可扩展的标记语言&#xff0c;以其灵活的数据表示方式和良好的跨平台性&#xff0c;在程序配置、数据交换等方面发挥着重要作用。本文将详…