在存储库服务中检索用户 http 数据

Retrieve users http data in repository service

我目前正在构建一个应用程序,其中每个用户都有一个唯一的密钥存储在用户的会话存储中。此密钥用于解密数据库中的用户数据。由于应用程序的存储库层处理数据库查询(使用 Dapper),我希望在那里进行解密。

现在的问题是:我可以从会话存储中检索用户密钥,将其传递给控制器​​,然后传递给服务,然后在链接的每个方法中使用名称为 "key" 的参数传递给存储库.有没有一种方法可以将密钥从控制器传递到存储库层,而无需在每次调用中手动包含密钥?

如果有比将它存储在会话存储中更好的解决方案,我愿意接受它,如果它会让这更容易。

我遵循的加密系统如下(来自另一个SO答案):

您可以在您的存储库或其他相关业务服务中注入 IHttpContextAccessor 以检索用户密钥。

假设您在 Header 的 Http 请求中将用户密钥发送为 UserKey:

在你的Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddHttpContextAccessor();
    ...
}

在您的存储库中:

public Repository(IHttpContextAccessor httpContextAccessor, ...)
{
    ...
    var userKey = httpContextAccessor.HttpContext.Request.Headers["UserKey"].FirstOrDefault();

    // Or if you send it as cookie: 
    // var userKey = httpContextAccessor.HttpContext.Request.Cookies["UserKey"];
    ...
}

当然你可以像接受的答案那样做,但我仍然不推荐它

我假设您有一些像 ProjectName.RepositoriesProjectName.DAL 这样的程序集,您的所有存储库都在其中 要在那里使用 IHttpContextAccessor,您应该安装 Microsoft.AspNetCore.Http 作为依赖项

所以现在您的存储库级别知道“我们正在使用什么框架来处理请求”并且它使用当前 HttpContext 来获取一些数据

但是为了在组件之间提供低耦合,我们不应该依赖这样的细节

因此我们可以编写一些用户定义的容器 class 以将 UserKey 传输到我们的存储库级别

我的建议有代码:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<UserKeyContainer>();
    services.AddTransient<IUserRepository, UserRepository>();
    ...
}

在抽象层或 Dto 层的某处你将拥有

public class UserKeyContainer
{
    public string UserKey { get; set; }
}

控制器代码:

[Route("[controller]")]
public class UserController : Controller
{
    private readonly UserKeyContainer _keyContainer;
    private readonly IUserRepository _repository;
    public UserController(UserKeyContainer keyContainer, IUserRepository repository)
    {
        _keyContainer = keyContainer;
        _repository = repository;
    }

    [HttpGet("")]
    public IActionResult Get()
    {
        _keyContainer.UserKey = "dasdasd"; //you should get UserKey from request there
        _repository.SomeMethod();
        return Ok();
    }
}

和存储库:

public class UserRepository : IUserRepository
{
    private readonly UserKeyContainer _keyContainer;
    public UserRepository(UserKeyContainer keyContainer)
    {
        _keyContainer = keyContainer;
    }

    public void SomeMethod()
    {
        var key = _keyContainer.UserKey;
    }
}

您还可以使用操作过滤器拦截请求并将 HttpContext 数据设置为 UserKey