详解.NET 6 Web API中通过Token获取当前登录用户信息

南乔
南乔
发布时间:2026-10-16| 8人浏览过
原创

在前序的.NET 6 TodoList开发文章中,我们在领域实体保存时硬编码了`Anonymous`作为创建和修改者,导致数据缺乏可追溯性。本文的目标是实现自动获取当前登录用户的信息,并将其正确写入数据库。

目标与原理

核心目标是:实现在保存数据时填入当前登陆的操作用户名。 原理上,当用户通过认证后,返回的JWT(JSON Web Token)的payload部分包含了用户的Claim信息(如UserName)。我们需要利用.NET提供的IHttpContextAccessor对象,从当前请求上下文中提取这些Claim,进而获取到用户名,并在数据库层面对其进行持久化。

准备条件

1. 已完成的.NET 6 Web API基础架构。 2. 已实现的JWT认证逻辑,确保Token中包含ClaimTypes.Name(即UserName)。 3. 用于测试的TodoList应用及相关的领域实体模型。

真实操作顺序

第1步:定义当前用户服务接口

目的:定义抽象契约,解耦具体实现,便于后续测试和维护。

入口:Application/Common/Interfaces目录

动作:新建 ICurrentUserService.cs,声明一个只读属性用于暴露用户名:

namespace TodoList.Application.Common.Interfaces;

public interface ICurrentUserService
{
    string? UserName { get; }
}

参数说明:若需获取UserId或其他信息,需在JWT签发时的Claims生成代码中添加相应字段。例如演示代码中添加了Role和Name:

// 演示了返回用户名和Role两个claims
var claims = new List<Claim>
{
    // Claims中包含UserName信息
    new(ClaimTypes.Name, User!.UserName),
    new(JwtRegisteredClaimNames.Iss, _jwtConfiguration.ValidIssuer ?? "TodoListApi"),
    new(JwtRegisteredClaimNames.Aud, _jwtConfiguration.ValidAudience ?? "http://localhost:5050")
};

第2步:实现用户服务接口

目的:通过HTTP上下文获取当前认证用户的实际名称。

入口:Api/Services目录

动作:新建 CurrentUserService.cs,注入IHttpContextAccessor并读取Claims:

using System.Security.Claims;
using TodoList.Application.Common.Interfaces;

namespace TodoList.Api.Services;

public class CurrentUserService : ICurrentUserService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CurrentUserService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    // 通过注入的IHttpContextAccessor获取`HttpContext.User(ClaimsPrinciple)`中对应的Claims信息
    public string? UserName  => _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.Name);
}

重要配置:必须在 Program.cs 中将此服务注册为单例(Singleton),以确保整个生命周期内共享同一个访问器实例:

builder.Services.AddSingleton<ICurrentUserService, CurrentUserService>();

第3步:在DbContext中使用该服务

目的:在每次保存更改前,自动填充审计字段。

入口:TodoListDbContext.cs

动作A:构造函数注入。将ICurrentUserService加入构造函数参数:

private readonly ICurrentUserService _currentUserService;
public TodoListDbContext(
    DbContextOptions<TodoListDbContext> options,
    IDomainEventService domainEventService,
    ICurrentUserService currentUserService) : base(options)
{
    _domainEventService = domainEventService;
    _currentUserService = currentUserService;
}

动作B:重写SaveChangesAsync。遍历变更追踪中的AuditableEntity,根据状态设置用户和时间:

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new())
{
    foreach (var entry in ChangeTracker.Entries<AuditableEntity>())
    {
        switch (entry.State)
        {
            case EntityState.Added:
                entry.Entity.CreatedBy = _currentUserService.UserName;
                entry.Entity.Created = DateTime.UtcNow;
                break;
            case EntityState.Modified:
                entry.Entity.LastModifiedBy = _currentUserService.UserName;
                entry.Entity.LastModified = DateTime.UtcNow;
                break;
        }
    }
    // 省略其他...
    return await base.SaveChangesAsync(cancellationToken);
}

验证

启动 Api 项目,首先通过认证接口获取合法的 Token。接着使用该 Token 发起请求,创建一个新的 TodoList 任务。

从请求响应或日志中可以看到,新创建的记录已携带当前用户信息。为确保数据确实落盘,我们直接查询数据库进行最终确认:

数据库结果显示,CreatedBy 和 LastModifiedBy 字段已成功填充为当前登录用户名,而非之前的占位符。

总结

本文详细介绍了在.NET 6应用中,如何结合JWT认证机制与EF Core的拦截器功能,自动处理数据审计信息的录入。通过IHttpContextAccessor解析Token中的Claim,再配合依赖注入在DbContext层面统一处理,既保证了业务逻辑的纯净,又实现了关键数据的自动化记录。以上就是.NET 6实现获取当前登录用户信息并自动落盘的详细内容,更多关于.NET 6获取当前登录用户信息的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。