- qimi liwenzhou 博客
- 有很多点还没搞清楚,包括业务语法,有待加强
简历
- 关键在于登录注册投票帖子展示等功能的实现
- 然后一些库函数,一些算法等
- 再就是性能分析
库函数
viper
Viper是 Go 语言中一款功能强大的配置管理库,旨在简化应用程序的配置处理。它支持多种配置文件格式,包括 JSON、TOML、YAML、HCL、envfile 和 Java properties 等。此外,Viper 还提供了从环境变量、命令行标志、远程配置系统(如 etcd 或 Consul)以及直接在代码中设置配置值的功能。
sqlx
sqlx
是 Go 语言中的一个库,扩展了标准的 database/sql
库,简化了数据库操作,提供了更多的功能和便捷的方法,尤其是在处理结构体与数据库表之间的映射时。它的目标是提供比原生 database/sql
更简洁、更高效的数据库操作方式,同时仍保持与标准库的兼容性。
lumberjack
lumberjack
是 Go 语言中的一个库,主要用于 日志轮转(log rotation)和 日志文件管理。它提供了自动的日志文件切割功能,可以避免日志文件过大,从而有效管理日志的存储空间
zap
- 能够将事件记录到文件中,而不是应用程序控制台。
- 日志切割-能够根据文件大小、时间或间隔等来切割日志文件。
- 支持不同的日志级别。例如INFO,DEBUG,ERROR等。
- 能够打印基本信息,如调用文件/函数名和行号,日志时间等
validator
validator
是一个用于 Go 语言的强大且灵活的数据验证库,通常用于验证结构体中的字段是否符合某些规则。它通过标签(tags)来指定验证规则,支持各种常见的数据验证功能,例如字符串长度、邮箱格式、正则表达式匹配、数值范围等。
设计理念
基于雪花算法生成用户id
分布式ID生成器
- 全局唯一性:不能出现有重复的ID标识,这是基本要求
- 递增性:确保生成ID对于用户或业务是递增的
- 高可用性:任何情况都能生成正确的ID
- 高性能性,高并发环境下表现良好
bwmarrn/snowflake
1bit Unused | 41bit 时间戳 | 10bit 机器ID | 12bit 序列号
snoy/snoyflake
1 + 39 +8(序列号) + 16(机器id)
用户认证
HTTP是一个无状态的协议,一次请求结束后,下次再发送服务器就不知道请求由谁发送了(一个IP不代表一个用户),在Web应用中,用户的认证和鉴权十分重要。
Cookie-Session认证模式
- 客户端使用用户名,密码验证
- 服务端验证用户名,密码正确后生成并存储Session,将SessionID通过Cookie返回客户端
- 客户端访问需要认证的接口时在Cookie中携带SessionID
- 服务端通过SessionID查找Session并进行鉴权,返回客户端需要的数据
但是,基于session方式存在多种问题:
- 服务端需要存储session在内存中(需要快速查找),用户多时占用服务器资源较多。
- 当需要扩展时,创建session的服务器可能不是验证session的服务器,还需要共享所有的session
- 由于客户端使用cookie存储sessionID,跨域场景下需要进行兼容处理,同时这种方式以防范CSRF攻击
Token认证模式
基于Token的无状态会话管理,服务端不再存储信息,逻辑如下
- 客户端使用用户名,密码认证
- 服务端验证用户名密码是否正确,生成Token返回客户端
- 客户端保存Token,访问需要认证的接口时在URL参数或者HTTP header种加入token
- 服务端解码Token进行鉴权,返回客户端需要的数据
解决了Session会话管理带来的问题
- 服务端不需要存储和用户鉴权有关的信息,鉴权信息会被加密到token种,服务端只读取token包含的鉴权信息即可
- 避免了共享session导致的不易扩展
- 不需要依赖cookie,避免了相关的CSRF攻击
- 使用CORS可以快速解决跨域问题
JWT
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于安全地在各方之间传递信息。JWT 通常用于身份认证和授权场景,尤其是在 Web 应用和 API 中。它可以作为一种紧凑、URL 安全的方式来表示声明(claims),并且通常由三部分组成:头部、有效载荷和签名。
JWT 的组成
一个 JWT 通常由三部分组成
- Header通常包含算法和类型(JWT)(Base64 编码):
eyJhbGciOiAiSFMyNTYiLCJ0eXAiOiAiSldUIn0
- Payload包含用户信息或声明(如用户 ID、角色等)(Base64 编码):
eyJzdWIiOiAiMTIzNDU2Nzg5MCIsIm5hbWUiOiAiSm9obiBEb2UiLCJpYXQiOiAxNTE2MjM5MDIyfQ
- Signature使用密钥对前两部分进行加密,确保数据完整性f:使用密钥
"secret"
对前两部分进行加密。
分别用点(.
)分隔,格式如下:
1
header.payload.signature
特点
- 自包含(Self-contained):JWT 将所有必要的信息(如用户身份、权限等)存储在令牌中,因此服务器无需存储会话信息。它是自包含的。
- 无状态(Stateless):JWT 不需要服务器保持会话状态。服务器只需要验证 JWT 的有效性,无需存储用户的任何会话数据。
- 紧凑性(Compact):由于采用了 Base64 编码,JWT 非常小且适合在 URL、HTTP 头或 Cookie 中传输。
- 可验证性(Verifiable):JWT 的签名部分确保了数据的完整性和真实性。通过公共密钥或共享密钥可以验证 JWT 是否被篡改。
- 跨域支持:JWT 是通过 HTTP 头部传递的,可以轻松支持跨域请求,在 RESTful API 或微服务架构中非常常见。
缺点
- 暴露信息:JWT 的有效载荷部分没有加密,任何人都可以解码 JWT 查看其中的信息。如果需要存储敏感信息,必须使用加密的 JWT(JWE)。
- 不可撤销:一旦 JWT 被签发,直到它过期之前,服务器无法撤销它。因此,如果用户登出或权限改变,需要采用额外的机制来处理。
- 过期问题:如果没有设置合理的过期时间,JWT 可能会在长时间内有效,这增加了安全风险。
后端需要对外提供一个刷新Token的接口;前端需要实现一个当access Token过期时,自动刷新Token接口获取新Assess Token的拦截器。
redis实现投票,什么时候用mysql,什么时候用redis