详解.NET 6如何实现获取当前登录用户信息
作者:CODE4NOTHING 发布时间:2022-01-29 12:51:15
需求
在前面的文章里使用.NET 6开发TodoList应用之领域实体创建原理和思路,我们留了一个坑还没有填上,就是在数据库保存的时候,CreateUser和ModifiedUser我们当时填的都是Anonymous
,完成认证的功能后,现在我们需要实现在保存数据库的时候填入当前登陆进行操作的用户名。
目标
实现当前登陆用户信息获取。
原理和思路
原理很简单,在认证时拿到的Token里,payload中是包含登陆User的部分信息的,作为演示,我们需要想办法获取到用户名信息,并在保存数据时填入相应字段。为了获取Token中包含的用户信息,需要用到HttpContextAccessor
对象。很显然,需要一个新的接口和实现。
实现
创建当前用户获取接口
在Application/Common/Interfaces
中添加一个新的接口:
ICurrentUserService.cs
namespace TodoList.Application.Common.Interfaces;
public interface ICurrentUserService
{
string? UserName { get; }
}
这里我们取的是UserName,是因为在返回的Token中包含UserName的信息,如果需要使用UserId或其他信息,需要在GetClaims
中添加:
// 演示了返回用户名和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")
};
实现接口功能
在Api/Services
中添加类实现接口:
CurrentUserService.cs
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
中添加依赖注入:
Program.cs
builder.Services.AddSingleton<ICurrentUserService, CurrentUserService>();
使用功能
接下来我们去修改DbContext,需要先在构造函数中注入:
TodoListDbContext.cs
private readonly ICurrentUserService _currentUserService;
public TodoListDbContext(
DbContextOptions<TodoListDbContext> options,
IDomainEventService domainEventService,
ICurrentUserService currentUserService) : base(options)
{
_domainEventService = domainEventService;
_currentUserService = currentUserService;
}
在SaveChangesAsync
方法中修改:
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;
}
}
// 省略其他...
}
验证
启动Api
项目,首先获取Token,再用获取到的Token去创建一个新的TodoList:
可以看到新创建的TodoList的用户信息已经获取到了,为了确保数据存储到数据库中,我们去数据库看一下:
来源:https://www.cnblogs.com/code4nothing/p/15816590.html


猜你喜欢
- 本文介绍在使用C#开发WinForm程序时,如何使用自定义的XML配置文件。虽然也可以使用app.config,但命名方面很别扭。我们在使用
- 今天实现一个很多app中使用到的加载进度条的效果,可能我们平时数据加载都使用到的是系统自带的,但是也有很多app加载进度条的效果实现挺好看,
- 一、简介Lock关键字是Monitor的一种替换用法,lock在IL代码中会被翻译成Monitor. lock (obj) &nb
- 主要思路是调用系统文件管理器或者其他媒体采集资源来获取要上传的文件,然后将文件的上传进度实时展示到进度条中。主Activitypackage
- 1、定义一个接口 Animalpackage com.zh.vo;public interface Animal { void
- " 梧桐更兼细雨,到黄昏、点点滴滴。"C语言朱武大战数据结构专栏C语言植物大战数据结构快速排序图文示例C语言植物大战数据
- 定义枚举类型时本质上就是在定义一个类,只不过很多细节由编译器帮您补齐了,所以某些程度上,enum关键字的 作用就像是class或interf
- 本文实例为大家分享了Android实现Window弹窗效果的具体代码,供大家参考,具体内容如下效果图第一步 准备弹窗的布局,新建XML文件
- 简介java中可以被称为Number的有byte,short,int,long,float,double和char,我们在使用这些Nubme
- OpenCV概述OpenCV做为功能强大的计算机视觉开源框架,包含了500多个算法实现,而且还在不断增加,其最新版本已经更新到3.2。其SD
- 普通商户分账功能分账比例:目前只有”低比例分账“小于等于30%分账,分账金额需要减去(千6)手续费.每一张订单只能分发,当前订单总额的百分之
- 在C#中,当引用类型需要转换的时候,经常会用到关键字is、as以及显式强转。本篇来体验这三者的用法。先来梳理.NET引用类型转换的"
- GB2312是简体中文系统的标准编码 用“区” 跟“位”的概念表示 称之为区位码 区指代大的范围 位相当于偏移量。每个汉字占两个字节高位字节
- Docker 是一种“轻量级”容器技术,它几乎动摇了传统虚拟化技术的地位,现在国内外已经有越来越多的公司开始逐步使用 Docker 来替换现
- 本文实例讲述了C#调用存储过程的方法。分享给大家供大家参考,具体如下:CREATE PROCEDURE [dbo].[GetNameById
- 前言大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什
- 前言最近测试给我提了一个bug,说我之前提供的一个批量复制商品的接口,产生了重复的商品数据。追查原因之后发现,这个事情没想象中简单,可以说一
- 异步log4j2的location信息打印问题背景:项目改造过程中将log4j2改成异步,发现行号没有打印,于是扒了下官方文档,大概陈述下:
- 一、spring-boot-devtools在pom中直接引入依赖<dependency> <groupId&
- 下面是一些我找到Android的ADB有用的命令。可以手动或使用自动构建和测试过程。查看设备adb devices如果多个设备连接则使用 u