use. NET 6 to develop TodoList application (pit filling 1) -- to obtain the current login user

Series navigation and source code

demand

In the previous article use. NET 6 to develop TodoList application (5) -- domain entity creation , we left a hole that has not been filled in. When the database is saved, CreateUser and ModifiedUser were filled in Anonymous. After completing the authentication function, now we need to fill in the user name currently logged in for operation when saving the database.

target

Achieve the current login user information acquisition.

Principles and ideas

The principle is very simple. In the Token obtained during authentication, the payload contains some information about logging in to the User. As a demonstration, we need to find a way to obtain the User name information and fill in the corresponding fields when saving data. In order to obtain the User information contained in the Token, you need to use the HttpContextAccessor object. Obviously, a new interface and implementation are needed.

realization

Create current user acquisition interface

Add a new interface in Application/Common/Interfaces:

  • ICurrentUserService.cs
namespace TodoList.Application.Common.Interfaces;

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

Here we take UserName because the returned Token contains the UserName information. If you need to use UserId or other information, you need to add the following in GetClaims:

// Demonstrates the two claims of returning user name and Role
var claims = new List<Claim>
{
    // Claims contains UserName information
    new(ClaimTypes.Name, User!.UserName),
    new(JwtRegisteredClaimNames.Iss, _jwtConfiguration.ValidIssuer ?? "TodoListApi"),
    new(JwtRegisteredClaimNames.Aud, _jwtConfiguration.ValidAudience ?? "http://localhost:5050")
};

Implement interface functions

Add classes to Api/Services to implement interfaces:

  • 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;
    }

    // Get ` httpcontext. Com from the injected IHttpContextAccessor Corresponding Claims information in user (claimsprinciple) `
    public string? UserName  => _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.Name);
}

And add dependency injection in the Program:

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

Use function

Next, to modify the DbContext, we need to inject the following into the constructor:

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

Modify in the SaveChangesAsync method:

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;
        }
    }
// Omit other
}

verification

Start the Api project, first obtain the Token, and then use the obtained Token to create a new TodoList:

You can see that the user information of the newly created TodoList has been obtained. In order to ensure that the data is stored in the database, let's go to the database and have a look:

summary

In this paper, we realize how to obtain the current login user information from the request and save it to the database.

Keywords: webapi

Added by nelsok on Tue, 18 Jan 2022 13:31:57 +0200