我应该在哪里将代码以DDD和CQRS方式刷新访问令牌?

问题描述 投票:0回答:2

我正在使用ASP.NET Core并学习DDD和CQRS(包括MediatR)。我已阅读eshopcontainers文件。在我的应用程序中,我们需要在SQL DB中存储每个用户的Google访问令牌和刷新令牌,因为我们必须定期检查gmail中的某些状态。当我们实现该功能时,我们或多或少希望编写以下逻辑。

1. Get the access token and refresh token from our DB
2. If the access token is expired, we get the valid access token with refresh token
3. If the access token is updated in step 2, we save the new access token to DB
4. With the valid access token, we fetch information from gmail

此过程将在CQRS模式的多个命令处理程序中使用。

我的问题是,

  • 我应该在哪里用DDD,CQRS方式放置逻辑?应该将其放入存储库,应用程序服务还是域服务...?

  • 我们可以从查询处理程序中调用该方法吗?我不知道这是因为该逻辑有时会更新数据库中的数据,因此我认为我们不应从查询处理程序中调用此过程

我目前的想法是创建一个包含上述过程的UserService。我的解决方案结构的具体示例如下。 UserService将在多个命令处理程序中使用,并且在QueryHandler中不使用,因为它偶尔会进行数据库更新。但是,如果有一个基于DDD方式的更好的主意,我想知道。

解决方案结构

Application layer (depends on Domain and Infrastructure)
 - UserController.cs
 - CommandHandlers folder (several command handlers use UserService)
 - QueryHandlers folder 

Domain Layer (No dependency)
  - UserAggregate folder
    - User.cs (Model for user)
  - IRepository.cs (Interface)

Infrastructure Layer (depends on Domain)
  - EF Core related folder
  - Repository.cs (Implemented IRepository.cs)
  - UserService.cs (has the token update process)

User.cs

public class User 
{   
    public string AccessToken { get; set; }
    public string RefreshToken { get; set; }
    public long Id {get; set;}
}

UserService.cs(一个想法)

public class UserService 
{
    ....

    GetValidAccessToken(long userId) 
    {
        var user = repository.Find(userId);
        if (user.AccessToken is expired) 
        {
            var newAccessToken = GetNewAccesstokenWithRefreshToken(user.RefreshToken);
            user.AccessToken = newAccessToken;
            repository.Save(user);
        }
        return user.AccessToken;
    }
}
c# asp.net-core domain-driven-design cqrs mediatr
2个回答
2
投票

我同意@Ankit Vijay。请接受他的回答是正确的,因为我只会对此进行扩展。

您通常在需要授权访问的集成层中使用访问令牌。例如,Web API和其他视图控制器。使用消息队列时,消息处理程序不应公开公开,因此通常不需要授权。

据您所知,您需要使用访问令牌访问外部商店以获得特定于用户的数据。这意味着访问令牌可能会在尝试该操作之前过期。

据我所见,您有3个选择:

1)在初始集成点(例如Web api控制器)获得了相关信息,然后将这些数据传递。

2)传递用户名,并使用各种服务帐户来获得该服务帐户有权代表该用户的用户的访问令牌,然后使用该访问令牌来获取相关数据。

3)服务帐户可能有能力为用户收集此额外信息,在这种情况下,服务帐户将进行身份验证以获得令牌,然后为相关用户请求数据。

在我参与的上一个项目中,我们必须使用webMethods集成服务器,后端团队使用的是ADFS令牌。该令牌的有效期为8小时,由于各种原因,只有在此时间之后才执行某些操作。由于服务帐户对ADFS具有某种形式的委派权限,因此将为用户刷新过期的令牌。我没有参与该实现,但是从广义上讲,它是规避问题的想法。

如果您无法让服务帐户刷新令牌或直接获取所需的数据,我猜选项(1)将是您最好的选择。


1
投票

存储用户访问令牌和刷新令牌似乎与业务/域无关。我认为您不应该尝试通过DDD处理它。如果您需要在CommandHandlers中访问令牌,则将与访问令牌相关的逻辑放在Domain之外的某种中间件中。

© www.soinside.com 2019 - 2024. All rights reserved.