비밀번호의 암호화 위치, 엔티티 내부 vs 서비스 계층?

2023. 10. 17. 20:56Spring

728x90

위와 같은 단순한 게시판 프로젝트를 진행 중에 있다.

 

ERD

회원 엔티티의 password 필드는

프론트엔드에게서 받은 비밀번호를 암호화하여 저장하는 필드이다.

 

회원가입을 할 때 보통은 이 암호화라는 작업을 MemberService 계층 안에서 작업한다.

public class MemberService {

    private final MemberRepository memberRepository;
    private final PasswordEncoder passwordEncoder;


    //회원 등록
    @Transactional
    public void registerMember(MemberRegiDTO memberRegiDTO) {
        String name = memberRegiDTO.getName();
        String password = memberRegiDTO.getPassword();

        if (memberRepository.existsByName(name)) {
            throw new NameAlreadyExistsException(name);
        }

        Member member = new Member(name, passwordEncoder.encode(password));
        memberRepository.save(member);
    }

이렇게!

이유야, 암호화같은 비즈니스 작업은 보통 서비스 계층이 담당을 하니깐

Service 계층에서 작업을 하게 된다.

 

너무나 자연스럽게 위와 같이 하다 문득 이런 생각이 들었다.

 

당연한가...? 맞는 건 알겠는 데 그래도 뭔가 근거를 제시할 수 있지 않을까?

 

라는 생각이 들어, 한번 근거를 찾아보기로 했다.

재사용성: 암호화 로직은 여러 도메인에서 사용될 수 있습니다.
이를 서비스 레이어에 위치시키면 다른 도메인에서도 쉽게 재사용할 수 있습니다.

변경 용이성: 암호화 알고리즘이나 방식이 변경될 경우,
이를 도메인 모델 내부에 숨겨두면 해당 도메인 모델을 사용하는 모든 곳에서 수정이 필요할 수 있습니다.
반면, 서비스 레이어에서 처리하면 한 곳에서만 수정하면 됩니다.

의존성 관리: 암호화 라이브러리나 외부 서비스를 사용할 경우, 
도메인 모델이 이러한 외부 의존성에 종속되는 것을 피하고자 서비스 레이어에서 처리하는 것이 좋습니다.

되게 옳은 이유와 근거들이지만,

한편 또 되게 너무 이론적이라는 생각이 들기도 했다.

 

그렇다면 이런 이론적 근거보다는 

권위자, 절대자의 말을 인용해 보자라고 생각해

Domain-Driven Design: Tackling Complexity in the Heart of Software

라는 책을 찾아봤다.

Eric Evans

Business rules often do not fit the responsibility of any of the obvious ENTITIES or VALUE OBJECTS,
and their variety and combinations can overwhelm the basic meaning of the domain object.
But moving the rules out of the domain layer is even worse, since the domain code no longer expresses the model.

[의역]
비즈니스 규칙은 대부분 명확한 엔터티나 값 객체의 책임에 잘 맞지 않습니다.
그리고 그런 규칙들의 다양성과 조합 때문에 도메인 객체의 기본 의미가 흐려질 수도 있죠.
그런데, 이 규칙들을 도메인 계층에서 빼버리면 상황은 더 나빠집니다.
왜냐하면 도메인 코드가 더 이상 해당 모델을 제대로 표현하지 못하게 되니까요. 

DDD에서 얘기하는 도메인 계층은 요즘의 MVC 패턴으로 치면 

Service 계층, 엔티티 이 2가지입니다.

제 경우 암호화 라는 비즈니스 규칙은 사실 엔티티 내부에 있을 수도 있지만

회원 엔티티 값 객체의 책임, 즉 회원이라는 개념을 표현한다는 것에는 잘 맞지 않기 때문에

도메인 객체 내부에 넣는 건 별로입니다.

 

그래서 나머지 도메인 계층인 Service 계층에 넣는 게 좋다!

라는 결론~

728x90