2025-05-25 18:05:38 +08:00
|
|
|
|
# 用户管理
|
|
|
|
|
|
2025-05-31 12:03:22 +08:00
|
|
|
|
+ 创建用户
|
|
|
|
|
+ 删除用户
|
|
|
|
|
+ 更新用户
|
|
|
|
|
+ 用户列表
|
|
|
|
|
+ 用户详情
|
|
|
|
|
+ 重置密码
|
|
|
|
|
|
|
|
|
|
## 详情设计
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
// 定义User包的能力 就是接口定义
|
|
|
|
|
// 站在使用放的角度来定义的 userSvc.Create(ctx, req), userSvc.DeleteUser(id)
|
|
|
|
|
// 接口定义好了,不要试图 随意修改接口, 要保证接口的兼容性
|
|
|
|
|
type Service interface {
|
|
|
|
|
// 创建用户
|
|
|
|
|
CreateUser(context.Context, *CreateUserRequest) (*User, error)
|
|
|
|
|
// 删除用户
|
|
|
|
|
DeleteUser(context.Context, *DeleteUserRequest) (*User, error)
|
|
|
|
|
// 查询用户详情
|
|
|
|
|
DescribeUser(context.Context, *DescribeUserRequest) (*User, error)
|
|
|
|
|
// 查询用户列表
|
|
|
|
|
QueryUser(context.Context, *QueryUserRequest) (*types.Set[*User], error)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 业务功能
|
|
|
|
|
|
|
|
|
|
加解迷的方式有分类:
|
|
|
|
|
1. Hash (消息摘要): 单向Hash, 可以通过原文 获取摘要信息,但是无法通过摘要信息推断原文, 只要摘要信息相同,原文就相同: md5, sha*, bcrypt ...
|
|
|
|
|
2. 对称加解密: 加密和解密的秘密(key) 用于数据的加解密文
|
|
|
|
|
3. 非对称加解密: 加密(公钥)和解密(私用)不是用的同一个秘密, 用于密码的加解密
|
|
|
|
|
|
|
|
|
|
1. 用户密码怎么存储的问题, 存储用户密码的hash,避免直接存储用户密码。 11111 -> abcd, 可能导致 用户的秘密在其他平台泄露 知道了这个影视关系abcd --> 1111,
|
|
|
|
|
能不能有什么办法解决这个问题, 加盐: 相同密码 --> 每次hash会产生不同的结果
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
password --> hash
|
|
|
|
|
password + 随机字符串(salt) --> (salt)hash它也是随机
|
|
|
|
|
|
|
|
|
|
输入: password + 随机字符串(salt: 原来hash中的sal部分) == hash它也是随机(数据库)
|
|
|
|
|
|
2025-05-31 16:14:34 +08:00
|
|
|
|
```go
|
|
|
|
|
import (
|
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (req *CreateUserRequest) PasswordHash() {
|
|
|
|
|
if req.isHashed {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b, _ := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
|
|
|
|
req.Password = string(b)
|
|
|
|
|
req.isHashed = true
|
|
|
|
|
}
|
2025-05-31 12:03:22 +08:00
|
|
|
|
|
2025-05-31 16:14:34 +08:00
|
|
|
|
// 判断该用户的密码是否正确
|
|
|
|
|
func (u *User) CheckPassword(password string) error {
|
|
|
|
|
// u.Password hash过后的只
|
|
|
|
|
// (password 原始值 + hash值中提区salt)
|
|
|
|
|
return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
|
|
|
}
|
|
|
|
|
```
|
2025-06-08 10:05:58 +08:00
|
|
|
|
|
|
|
|
|
### 接口设计
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
ws.Route(ws.GET("").To(h.QueryUser).
|
|
|
|
|
Doc("用户列表查询").
|
|
|
|
|
Metadata(restfulspec.KeyOpenAPITags, tags).
|
|
|
|
|
Param(restful.QueryParameter("page_size", "分页大小").DataType("integer")).
|
|
|
|
|
Param(restful.QueryParameter("page_number", "页码").DataType("integer")).
|
|
|
|
|
Writes(Set{}).
|
|
|
|
|
Returns(200, "OK", Set{}))
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
其中 user字段里面的
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"password": "$2a$10$GoEjC.vFlgJ..BCvaMu6YurdVgyx4p6S4LFRXiqXESiVY4lokL496"
|
|
|
|
|
}
|
|
|
|
|
// 需要脱敏: "*"
|
|
|
|
|
{
|
|
|
|
|
"password": "****"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|