从其他有界上下文验证日期

问题描述 投票:1回答:1

我有两个有界上下文(studentenrollment,courses)。 Studentenrollment让所有学生都有他的课程ID和他的家庭作业。课程的管理部分包含与课程相关的所有信息。当学生想要获得课程的信息时,它会命中发送jwt令牌的端点(/ courses / ID)。在课程上下文中,我获得了学生ID,课程ID以及创建在公交车上发送的查询。在从课程ID获取课程信息之前的查询处理程序中,我想验证学生ID是否存在且该学生是否具有此课程。为此我必须调用另一个上下文有限的studentenrollment。所以,我一直在寻找如何在互联网上处理,我发现:https://medium.com/@martinezdelariva/authentication-and-authorization-in-ddd-671f7a5596ac

class findByCourseIdAndStudentIdQueryHandler()
    {
        public function handle($findByCourseIdAndStudentIdQuery)
        {
            $courseId = $findByCourseIdAndStudentIdQuery->courseId();
            $studentId = $findByCourseIdAndStudentIdQuery->studentId();

            $student = $this->collaboratorService->studentFrom(
                $courseId,
                $studentId
            );


            $this->courseRepository->findByCourseId($courseId);
        }
    }

    class collaboratorService()
    {
        public function studentFrom($courseId, $studentId)
        {
            $student = $this->studentEnrollmentClient->getStudentFrom($courseId, $studentId);

            if (!$student) {
                throw new InvalidStudentException();
            }

            return $student;
        }
    }

你怎么看?

更新

namespace App\Context\Course\Module\Course\UI\Controller;

class GetCourseController extends Controller
{
    public function getAction($request) {
        $this->ask(new FindByCourseIdQueryHandler($request->get('course_id'));
    }
}

namespace App\Context\Course\Module\Course\Infrastracture\Query;

class AuthorizedQueryDispatcher extends QueryDispatcher
{
    //In this case $query would be FindByCourseIdQueryHandler
    public function handle($query)
    {
        $authUser = $this->oauthService->getAuthUser();

        //it can be student or teacher
        $role = $authUser->getRole();
        $userId = $authUser->getUserId();

        //it will return FindByCourseIdAndStudentIdAuthorizedQueryHandler
        $authorizedQuery = $this->inflector->getAuthorizedQueryName->from($userId, $role, $query);

        $this->dispatch($authorizedQuery);

        $this->queryDispatch->dispatch($query);
    }
}

namespace App\Context\Course\Module\Course\Application\Query;

class FindByCourseIdAndStudentIdAuthorizedQueryHandler
{
    public function handle($findByCourseIdAndStudentIdQuery)
    {
        $student = $this->studentEnrollmentClient->getStudentFrom($findByCourseIdAndStudentIdQuery->courseId, $findByCourseIdAndStudentIdQuery->studentId);

        if (!$student) {
            throw new InvalidStudentException();
        }
    }
}

namespace App\Context\Course\Module\Course\Application\Query;

class findByCourseIdAndStudentIdQueryHandler()
{
    public function handle($findByCourseIdQueryHandler)
    {
        $courseId = $findByCourseIdQueryHandler->courseId();

        $this->courseRepository->findByCourseId($courseId);
    }
}
domain-driven-design cqrs
1个回答
1
投票

TLDR;授权应与Domain层明确分开,例如在不同的包/命名空间/模块中。此外,应该反转从域到授权的依赖关系,域不应该依赖/了解授权/

实现它的一种方法是创建一个授权服务,例如FindByCourseIdAndStudentIdQueryAuthorizer(让我们将它命名为Authorizer)。该服务可以跨越有界上下文(BC)边界,即它可以依赖于来自远程BC的远程域服务。理想情况下,当授权人进行检查时,远程数据应该已经可用。通过这种方式,系统在远程有界上下文服务不可用的情况下更具弹性。您可以通过侦听远程事件或后台任务来完成此操作。

理想情况下,域层(来自任何BC)不应该知道授权者。

一种方法是使用AuthorizedQueryDispatcher装饰应用程序的Composition根中的QueryDispatcher(或您拥有的)。这个AuthorizedQueryDispatcher,当它收到一个查询时,它首先搜索一个Authorizer,然后调用它。如果授权失败,则拒绝查询。如果授权成功或没有授权者,则查询将被发送到真实/装饰的QueryDispatcher。

如果不能这样做(即你没有QueryDispatcher)那么你可以尝试装饰每个查询处理程序(手工?)。例如,您可以使用与FindByCourseIdAndStudentIdAuthorizedQueryHandler具有相同界面的FindByCourseIdAndStudentIdQueryHandler。您可以在应用程序的组合根(DIC)中替换它们。

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