using Dpz.Core.Service.Mediator.Features.Account.Internal;
namespace Dpz.Core.Service.Mediator.Features.Account.Commands;
/// <summary>
/// 处理创建账号请求
/// </summary>
public class CreateAccountHandler(IRepository<User> repository, IConfiguration configuration)
: IRequestHandler<CreateAccountRequest, ResponseResult<string>>
{
/// <summary>
/// 创建账号并生成 BCrypt 密码和 SecurityStamp
/// </summary>
public async ValueTask<ResponseResult<string>> Handle(
CreateAccountRequest request,
CancellationToken cancellationToken
)
{
var result = new ResponseResult<string>();
if (string.IsNullOrWhiteSpace(request.Account))
{
return result.WithFail("账号不能为空");
}
if (string.IsNullOrWhiteSpace(request.Name))
{
return result.WithFail("昵称不能为空");
}
var actualPassword = string.IsNullOrEmpty(request.Password) ? "123456" : request.Password;
var entity = new User
{
Avatar = $"{configuration["CDNBaseAddress"]}/images/member.png",
CreateTime = DateTime.Now,
Id = request.Account,
LastUpdateTime = DateTime.Now,
Name = request.Name,
Permissions = request.Permissions ?? Permissions.Member,
Sex = Sex.Man,
Sign = "",
Enable = true,
Password = AccountSecurityHelper.CreatePasswordHash(actualPassword),
Key = AccountSecurityHelper.GenerateSecurityStamp(),
};
await repository.InsertAsync(entity, cancellationToken);
return result.WithOk(entity.Id);
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
代码解释
这是一个基于 CQRS(命令查询职责分离)模式 和 MediatR 库实现的账号创建命令处理器。
主要组成部分
1. 类定义
public class CreateAccountHandler(IRepository<User> repository, IConfiguration configuration)
: IRequestHandler<CreateAccountRequest, ResponseResult<string>>
主构造函数(C# 12 新特性):注入两个依赖
IRepository<User>:用户仓储,负责数据持久化IConfiguration:配置服务,用于读取配置项(如 CDN 地址)
实现接口:
IRequestHandler<TRequest, TResponse>- 请求类型:
CreateAccountRequest - 响应类型:
ResponseResult<string>(返回用户 ID)
- 请求类型:
2. 核心处理逻辑(Handle 方法)
参数验证
if (string.IsNullOrWhiteSpace(request.Account))
return result.WithFail("账号不能为空");
if (string.IsNullOrWhiteSpace(request.Name))
return result.WithFail("昵称不能为空");
验证必填字段:账号和昵称
密码处理
var actualPassword = string.IsNullOrEmpty(request.Password) ? "123456" : request.Password;
- 如果未提供密码,默认使用
"123456"
用户实体构建
var entity = new User
{
Avatar = $"{configuration["CDNBaseAddress"]}/images/member.png", // 从配置读取 CDN 地址
CreateTime = DateTime.Now,
Id = request.Account, // 使用账号作为主键
LastUpdateTime = DateTime.Now,
Name = request.Name,
Permissions = request.Permissions ?? Permissions.Member, // 默认权限为 Member
Sex = Sex.Man, // 默认性别
Sign = "",
Enable = true,
Password = AccountSecurityHelper.CreatePasswordHash(actualPassword), // BCrypt 加密
Key = AccountSecurityHelper.GenerateSecurityStamp(), // 生成安全戳
};
关键安全措施:
Password:使用 BCrypt 哈希算法加密(通过AccountSecurityHelper.CreatePasswordHash)Key:生成 SecurityStamp(用于令牌失效机制)
数据持久化
await repository.InsertAsync(entity, cancellationToken);
return result.WithOk(entity.Id);
异步插入数据库并返回成功结果
设计特点
安全性:
- 密码使用 BCrypt 加密存储
- 生成 SecurityStamp 支持会话管理
默认值处理:
- 默认密码:123456
- 默认权限:Member
- 默认头像:从配置文件读取
可扩展性:
- 使用仓储模式解耦数据访问
- 使用 MediatR 实现命令处理
- 配置外部化(CDN 地址等)
异步处理:
- 支持取消令牌(CancellationToken)
- 使用
ValueTask优化性能
潜在改进建议
- 添加重复检查:插入前验证账号是否已存在
- 密码强度验证:对自定义密码进行复杂度校验
- 审计日志:记录账号创建操作
- 事务处理:确保数据一致性
AI 正在分析代码…
评论加载中...