1. 배경

사용자 개인정보 보호를 위해 전화번호와 이메일을 데이터베이스에 AES로 암호화해 저장했다. 

마이페이지에서 사용자의 전화번호와 이메일을 복호화하여 보여주기 위해 MyBatis 쿼리에 복호화 함수를 적용했다.


2. 문제

복호화 함수를 적용했음에도 조회 결과가 VO에 매핑되지 않아 화면에는 암호화된 값이 그대로 노출되었다.

복호화 함수 자체는 DB에서 정상 작동하고 있었지만, API 응답에서는 값이 null로 내려왔다.

 

오류 발생한 쿼리

<select id="findUser" resultType="UserResponseVo">
    SELECT
      user_id,
      FN_DECRYPT_AES(phone_number),
      FN_DECRYPT_AES(email_address)
    FROM user__user
    WHERE user_id = #{userId}
</select>

 

VO

public class UserResponseVO {
	private String phoneNumber;
    private String emailAddress;
}

 

MyBatis에서 resultType은 쿼리의 컬럼명과 VO의 필드명이 정확히 일치해야 자동 매핑이 된다.

FN_DECRYPT_AES(phone_number)처럼 함수 호출 결과는 별칭(alias)이 없으면 함수 호출 문자열이 그대로 컬럼명으로 내려간다.

따라서 VO의 phoneNumber와 일치하지 않아 매핑되지 않았다.


3. 해결 방향

함수 결과에 별칭(alias)을 붙여 컬럼명과 필드명을 일치시킨다.

그 결과 복호화된 전화번호와 이메일이 정상적으로 VO에 매핑되었고 화면에도 복호화된 값이 정확히 출력되었다.

<select id="findUser" resultType="UserResponseVo">
    SELECT
      user_id,
      FN_DECRYPT_AES(phone_number)  AS phoneNumber,
      FN_DECRYPT_AES(email_address) AS emailAddress
    FROM user__user
    WHERE user_id = #{userId}
</select>

4. 회고

함수 호출이나 연산 컬럼은 반드시 별칭을 붙여야 한다는 MyBatis의 기본 원칙을 다시 확인할 수 있었다.

쿼리에서 별칭을 누락하면 복호화 함수가 잘 동작하고 있어도 매핑이 되지 않아 디버깅에 불필요한 시간을 쓸 수 있다.

+ Recent posts