← 전체 글로 돌아가기

웹 개발

권한 체크를 안전하게 변경하기

권한 관련 코드를 수정할 때 기존 사용자는 잠기고 새 사용자는 접근 못 하는 상황을 피하는 법.

권한 변경은 신중하게

권한 체크 로직을 건드리는 건 정말 조심해야 한다. 한 번 잘못 배포하면 사용자들이 갑자기 특정 기능에 접근 못 하게 될 수 있기 때문이다.

회사에서 겪은 가장 흔한 실수는 "권한 테이블을 정리하다가" 기존 사용자의 권한 레코드를 실수로 삭제하거나, 조건을 너무 엄격하게 바꿔서 대다수의 사용자가 차단되는 경우였다.

변경 전에 현재 상태를 기록하자

먼저 현재 시스템에서 어떤 사용자가 어떤 권한을 가지고 있는지 정확히 파악한다.

-- 사용자별 권한 분포 확인
SELECT role, COUNT(*) as count FROM user_roles GROUP BY role;

-- 특정 기능에 접근할 수 있는 사용자 수
SELECT COUNT(*) FROM users WHERE can_access_feature = true;

스크린샷이나 CSV로 이 정보를 저장해둔다. 나중에 배포 후 "어? 이게 맞나?"라고 확인할 때 필요하다.

점진적으로 변경하기

큰 권한 변경은 한 번에 하지 않는다. 예를 들어 새로운 역할(role)을 추가하려면:

  1. 새 역할을 DB에만 추가한다 (코드에서 아직 사용 안 함)
  2. 코드에서 새 역할을 읽을 수 있도록 한다 (아직 권한 부여 안 함)
  3. 테스트 사용자에게만 새 역할을 할당한다
  4. 모니터링하면서 문제가 없으면 일반 사용자에게 확대한다

테스트하기

배포 전에 로컬에서 여러 역할로 로그인해서 테스트한다.

# 관리자로 로그인 → 모든 기능 접근 가능
# 일반 사용자로 로그인 → 정해진 기능만 접근 가능
# 새로운 역할로 로그인 → 예상대로 동작하는지 확인

특히 권한이 없는 경우를 확인하는 게 중요하다. 권한 없을 때 빈 화면만 나오는 게 아니라 "접근 권한이 없습니다" 같은 메시지를 표시하는지 확인하자.

배포 후 모니터링

배포 후 1시간 동안은 에러 로그를 자주 본다. 사용자들이 "로그인이 안 된다"거나 "버튼이 사라졌다"고 신고할 수도 있다.

// 권한 체크에 실패할 때 로그를 남긴다
if (!hasPermission(user, 'feature_name')) {
  logger.warn('Access denied', {
    userId: user.id,
    feature: 'feature_name',
    timestamp: new Date()
  });
}

문제가 생기면 롤백할 수 있도록 배포 전에 버전을 명확히 기록해두자.