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

Where should I put the code for refreshing access token with a DDD & CQRS manner?

我正在使用 ASP.NET Core 并学习 DDD 和 CQRS(包括 MediatR)。我已阅读 eshopcontainers 个文件。在我的应用程序中,我们需要在我们的 SQL 数据库中存储 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模式的几个命令处理程序中。

我的问题是,

我目前的想法是创建一个包含上述过程的 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;
    }
}

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

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

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

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

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

1) 您在初始集成点获取相关信息,例如网络 api 控制器,然后传递该数据。

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

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

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

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