当前用户
Dddify 提供了 ICurrentUser 接口,用于简化当前用户身份的获取和使用,业务代码无需关心具体实现,解耦业务逻辑与身份管理,增强代码可测试性。
接口定义
基础属性
ICurrentUser 接口定义了以下属性,用于获取当前用户的核心基本信息:
Principal:提供当前用户的声明主体,此属性为ClaimsPrincipal?类型。IsAuthenticated:指示当前用户是否经过身份验证,此属性为bool类型。Id:获取当前用户的唯一标识符,此属性为Guid?类型。Name:获取当前用户的姓名,此属性为string?类型。Roles:获取当前用户的角色,此属性为IEnumerable<string>?类型。
扩展方法
ICurrentUser 提供了直接使用 Principal 声明的扩展方法:
GetAllClaims():获取所有的声明。FindClaim(string claimType):查找指定类型声明。FindClaims(string claimType):查找指定类型所有声明。FindClaimValue(string claimType):查找指定类型声明值。FindClaimValue<T>(string claimType):查找指定类型声明值,并转换数据类型。
实现 ICurrentUser 接口
定义一个类,实现 ICurrentUser 接口,并通过 IHttpContextAccessor 从 HTTP 请求上下文中获取当前用户信息。
示例:演示如何通过 HttpContext 获取当前用户信息。
C#
public class HttpContextUser(IHttpContextAccessor httpContextAccessor) : ICurrentUser
{
public ClaimsPrincipal? Principal => httpContextAccessor.HttpContext?.User;
public bool IsAuthenticated => Id.HasValue;
public Guid? Id => this.FindClaimValue(ClaimTypes.NameIdentifier)?.ToGuid();
public string? Name => this.FindClaimValue(ClaimTypes.Name);
public IEnumerable<string>? Roles => this.FindClaims(ClaimTypes.Role).Select(c => c.Value);
}注册服务
在 Program.cs 中注册 ICurrentUser 服务:
C#
builder.Services.AddHttpContextAccessor();
builder.Services.AddDddify(cfg =>
{
cfg.AddCurrentUser<HttpContextUser>();
});使用 ICurrentUser
通过依赖注入使用 ICurrentUser 接口来获取当前用户的信息。
示例:
C#
[ApiController]
public class UserController(ICurrentUser currentUser) : ControllerBase
{
[HttpGet("info")]
public IActionResult GetUserInfo()
{
if (!currentUser.IsAuthenticated)
{
return Unauthorized();
}
return Ok(new
{
Id = currentUser.Id,
Name = currentUser.Name,
Roles = currentUser.Roles
});
}
}扩展 ICurrentUser
根据项目需求,可以扩展 ICurrentUser 接口,添加更多属性或方法(如多租户、动态角色、自定义声明)。
下面是一个简单的示例,演示如何来扩展 ICurrentUser 接口。
首先,定义一个新的接口 IExtendedCurrentUser,继承 ICurrentUser 接口,并声明需要额外添加的用户属性。
C#
// 以下是一些常见的扩展场景:
public interface IExtendedCurrentUser : ICurrentUser
{
// 扩展:获取用户邮箱
string Email { get; }
// 扩展:获取用户电话号码
string PhoneNumber { get; }
// 扩展:获取当前租户 ID
Guid? TenantId { get; }
}接下来,定义一个新的类 ExtendedCurrentUser,实现 IExtendedCurrentUser 接口,注入 ICurrentUser 继承原始属性,然后按业务需求实现额外添加的属性取值逻辑。
C#
public class ExtendedCurrentUser(ICurrentUser currentUser) : IExtendedCurrentUser
{
public Guid? Id => currentUser.Id;
public string? Name => currentUser.Name;
public ClaimsPrincipal? Principal => currentUser.Principal;
public bool IsAuthenticated => currentUser.IsAuthenticated;
public string Email => "johndoe@example.com"; // 示例邮箱
public string Role => "Admin"; // 示例角色
}最后,需要在应用启动时将扩展服务也注册到 DI 容器。打开 Program.cs 文件,进行如下代码调整:
C#
builder.Services.AddDddify(cfg =>
{
cfg.AddCurrentUser<HttpContextUser>();
cfg.AddCurrentUser<HttpContextUser, IExtendedCurrentUser, ExtendedCurrentUser>();
});如此以来,可以通过注入 IExtendedCurrentUser 接口来访问当前用户。以下是一个简单的使用示例:
C#
public class AccountController(IExtendedCurrentUser currentUser) : ControllerBase
{
public ActionResult GetUserInfo()
{
Console.WriteLine($"Email: {currentUser.Email}"); // 输出: "johndoe@example.com"
Console.WriteLine($"Role: {currentUser.Role}"); // 输出: "Admin"
}
}
