域驱动设计中的密码验证

Password validation in Domain Driven Design

我正在做一个示例项目,以便更深入地了解 DDD。假设我们有一个案例,用户需要更改密码。

通常通过提供 current passwordnew password 来更改当前密码。现在我要检查的是作为 API 参数传递的 current password 实际上是存储在 DB.

中的那个

通常密码存储为哈希,并且通常有像 Spring 这样的库提供一个抽象来使用。

现在密码匹配是 Domain Concept,因此应该是 User Entity 的一部分,但是匹配密码的方式将取决于算法,因此可能是 Infrastructure

那么密码匹配逻辑去哪里了呢?

控制器是否匹配密码,然后调用

UserEntity.ChangePassword(newPassword)

或者 userEntity 是否有方法

UserEntity.ChangePassword(oldPassword, newPassword) {

    PasswordValidator validator = new PasswordValidator(); // where PasswordValidator is a framework class 
    boolean doesMatch = validator.validate(currentPassInDB, oldPassword);
    if (!doesMatch)
        return; // throw error
    this.currentPassInDB = doSomething(newPassword);
}

如果采用方法 2,则框架 类 将泄漏到域 Class。我在这里很困惑。密码是 value object?

您很可能会在域中声明一个用于加密或验证密码的接口。该接口将在基础设施层中实现。

AR 本身可能依赖于接口:

user.changePassword(oldPassword, newPassword, validator);

或者您可以在域服务中实现逻辑,该逻辑将编排用例,将 AR 与该依赖项分离(我更喜欢前者)。

这类似于 Vaughn Vernon 通过声明 EncryptionService interface which is then leveraged in the AuthenticationService 域服务来处理身份验证的方式。